From 08aa4418c30cfc18ccc69a0f0f9cb9e17be6c196 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Mon, 12 Aug 2013 09:28:15 +0200 Subject: Update to MediaWiki 1.21.1 --- tests/.htaccess | 1 - tests/RunSeleniumTests.php | 233 - tests/TestsAutoLoader.php | 35 - tests/jasmine/.htaccess | 1 - tests/jasmine/SpecRunner.html | 28 - tests/jasmine/lib/jasmine-1.0.1/MIT.LICENSE | 20 - tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js | 188 - tests/jasmine/lib/jasmine-1.0.1/jasmine.css | 166 - tests/jasmine/lib/jasmine-1.0.1/jasmine.js | 2421 ----- .../jasmine/spec/mediawiki.jqueryMsg.spec.data.js | 488 - tests/jasmine/spec/mediawiki.jqueryMsg.spec.js | 389 - tests/jasmine/spec_makers/makeJqueryMsgSpec.php | 110 - tests/parser/README | 8 - tests/parser/extraParserTests.txt | Bin 1261 -> 0 bytes tests/parser/parserTest.inc | 1330 --- tests/parser/parserTests.txt | 10363 ------------------- tests/parser/parserTestsParserHook.php | 70 - .../parser/preprocess/All_system_messages.expected | 5646 ---------- tests/parser/preprocess/All_system_messages.txt | 5645 ---------- tests/parser/preprocess/Factorial.expected | 17 - tests/parser/preprocess/Factorial.txt | 16 - tests/parser/preprocess/Fundraising.expected | 18 - tests/parser/preprocess/Fundraising.txt | 17 - tests/parser/preprocess/QuoteQuran.expected | 140 - tests/parser/preprocess/QuoteQuran.txt | 139 - tests/parserTests.php | 92 - tests/phpunit/Makefile | 91 - tests/phpunit/MediaWikiLangTestCase.php | 42 - tests/phpunit/MediaWikiPHPUnitCommand.php | 76 - tests/phpunit/MediaWikiTestCase.php | 547 - tests/phpunit/README | 53 - tests/phpunit/StructureTest.php | 60 - tests/phpunit/TODO | 10 - tests/phpunit/bootstrap.php | 32 - tests/phpunit/data/db/mysql/functions.sql | 12 - tests/phpunit/data/db/postgres/functions.sql | 12 - tests/phpunit/data/db/sqlite/tables-1.13.sql | 342 - tests/phpunit/data/db/sqlite/tables-1.15.sql | 454 - tests/phpunit/data/db/sqlite/tables-1.16.sql | 483 - tests/phpunit/data/db/sqlite/tables-1.17.sql | 516 - tests/phpunit/data/db/sqlite/tables-1.18.sql | 535 - tests/phpunit/data/media/1bit-png.png | Bin 167 -> 0 bytes tests/phpunit/data/media/80x60-2layers.xcf | Bin 1162 -> 0 bytes tests/phpunit/data/media/80x60-Greyscale.xcf | Bin 667 -> 0 bytes tests/phpunit/data/media/80x60-RGB.xcf | Bin 677 -> 0 bytes .../Animated_PNG_example_bouncing_beach_ball.png | Bin 72209 -> 0 bytes tests/phpunit/data/media/Gtk-media-play-ltr.svg | 35 - tests/phpunit/data/media/Png-native-test.png | Bin 4665 -> 0 bytes tests/phpunit/data/media/QA_icon.svg | 77 - tests/phpunit/data/media/README | 38 - tests/phpunit/data/media/Toll_Texas_1.svg | 150 - .../media/US_states_by_total_state_tax_revenue.svg | 248 - tests/phpunit/data/media/Wikimedia-logo.svg | 14 - .../data/media/Xmp-exif-multilingual_test.jpg | Bin 12544 -> 0 bytes tests/phpunit/data/media/animated-xmp.gif | Bin 3864 -> 0 bytes tests/phpunit/data/media/animated.gif | Bin 497 -> 0 bytes tests/phpunit/data/media/broken_exif_date.jpg | Bin 3233 -> 0 bytes tests/phpunit/data/media/exif-gps.jpg | Bin 665 -> 0 bytes tests/phpunit/data/media/exif-user-comment.jpg | Bin 484 -> 0 bytes tests/phpunit/data/media/greyscale-na-png.png | Bin 365 -> 0 bytes tests/phpunit/data/media/greyscale-png.png | Bin 415 -> 0 bytes tests/phpunit/data/media/iptc-invalid-psir.jpg | Bin 9574 -> 0 bytes tests/phpunit/data/media/iptc-timetest-invalid.jpg | Bin 9573 -> 0 bytes tests/phpunit/data/media/iptc-timetest.jpg | Bin 9573 -> 0 bytes tests/phpunit/data/media/jpeg-comment-binary.jpg | Bin 448 -> 0 bytes .../phpunit/data/media/jpeg-comment-iso8859-1.jpg | Bin 447 -> 0 bytes tests/phpunit/data/media/jpeg-comment-multiple.jpg | Bin 431 -> 0 bytes tests/phpunit/data/media/jpeg-comment-utf.jpg | Bin 445 -> 0 bytes tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg | Bin 499 -> 0 bytes tests/phpunit/data/media/jpeg-iptc-good-hash.jpg | Bin 499 -> 0 bytes tests/phpunit/data/media/jpeg-padding-even.jpg | Bin 450 -> 0 bytes tests/phpunit/data/media/jpeg-padding-odd.jpg | Bin 451 -> 0 bytes tests/phpunit/data/media/jpeg-xmp-alt.jpg | Bin 3255 -> 0 bytes tests/phpunit/data/media/jpeg-xmp-psir.jpg | Bin 3308 -> 0 bytes tests/phpunit/data/media/jpeg-xmp-psir.xmp | 35 - tests/phpunit/data/media/landscape-plain.jpg | Bin 38771 -> 0 bytes tests/phpunit/data/media/nonanimated.gif | Bin 200 -> 0 bytes tests/phpunit/data/media/portrait-rotated.jpg | Bin 38577 -> 0 bytes tests/phpunit/data/media/rgb-na-png.png | Bin 593 -> 0 bytes tests/phpunit/data/media/rgb-png.png | Bin 663 -> 0 bytes tests/phpunit/data/media/test.jpg | Bin 437 -> 0 bytes tests/phpunit/data/media/test.tiff | Bin 566 -> 0 bytes tests/phpunit/data/media/xmp.png | Bin 582 -> 0 bytes tests/phpunit/data/xmp/1.result.php | 8 - tests/phpunit/data/xmp/1.xmp | 11 - tests/phpunit/data/xmp/2.result.php | 8 - tests/phpunit/data/xmp/2.xmp | 12 - tests/phpunit/data/xmp/3-invalid.result.php | 7 - tests/phpunit/data/xmp/3-invalid.xmp | 31 - tests/phpunit/data/xmp/3.result.php | 8 - tests/phpunit/data/xmp/3.xmp | 29 - tests/phpunit/data/xmp/4.result.php | 7 - tests/phpunit/data/xmp/4.xmp | 22 - tests/phpunit/data/xmp/5.result.php | 7 - tests/phpunit/data/xmp/5.xmp | 16 - tests/phpunit/data/xmp/6.result.php | 8 - tests/phpunit/data/xmp/6.xmp | 18 - tests/phpunit/data/xmp/7.result.php | 52 - tests/phpunit/data/xmp/7.xmp | 67 - tests/phpunit/data/xmp/README | 3 - tests/phpunit/data/xmp/bag-for-seq.result.php | 10 - tests/phpunit/data/xmp/bag-for-seq.xmp | 1 - tests/phpunit/data/xmp/flash.result.php | 8 - tests/phpunit/data/xmp/flash.xmp | 11 - tests/phpunit/data/xmp/gps.result.php | 12 - tests/phpunit/data/xmp/gps.xmp | 17 - .../data/xmp/invalid-child-not-struct.result.php | 7 - .../phpunit/data/xmp/invalid-child-not-struct.xmp | 12 - tests/phpunit/data/xmp/no-namespace.result.php | 7 - tests/phpunit/data/xmp/no-namespace.xmp | 11 - .../data/xmp/no-recognized-props.result.php | 2 - tests/phpunit/data/xmp/no-recognized-props.xmp | 8 - tests/phpunit/data/xmp/utf16BE.result.php | 12 - tests/phpunit/data/xmp/utf16BE.xmp | Bin 930 -> 0 bytes tests/phpunit/data/xmp/utf16LE.result.php | 12 - tests/phpunit/data/xmp/utf16LE.xmp | Bin 930 -> 0 bytes tests/phpunit/data/xmp/utf32BE.result.php | 12 - tests/phpunit/data/xmp/utf32BE.xmp | Bin 1856 -> 0 bytes tests/phpunit/data/xmp/utf32LE.result.php | 12 - tests/phpunit/data/xmp/utf32LE.xmp | Bin 1856 -> 0 bytes tests/phpunit/data/xmp/xmpExt.result.php | 8 - tests/phpunit/data/xmp/xmpExt.xmp | 13 - tests/phpunit/data/xmp/xmpExt2.xmp | 8 - tests/phpunit/data/zip/cd-gap.zip | Bin 182 -> 0 bytes tests/phpunit/data/zip/cd-truncated.zip | Bin 171 -> 0 bytes tests/phpunit/data/zip/class-trailing-null.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/class-trailing-slash.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/class.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/empty.zip | Bin 22 -> 0 bytes tests/phpunit/data/zip/looks-like-zip64.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/nosig.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/split.zip | Bin 196 -> 0 bytes tests/phpunit/data/zip/trail.zip | Bin 181 -> 0 bytes tests/phpunit/data/zip/wrong-cd-start-disk.zip | Bin 173 -> 0 bytes tests/phpunit/data/zip/wrong-central-entry-sig.zip | Bin 173 -> 0 bytes tests/phpunit/docs/ExportDemoTest.php | 36 - tests/phpunit/includes/ArticleTablesTest.php | 33 - tests/phpunit/includes/ArticleTest.php | 82 - tests/phpunit/includes/BlockTest.php | 230 - tests/phpunit/includes/CdbTest.php | 84 - tests/phpunit/includes/DiffHistoryBlobTest.php | 40 - tests/phpunit/includes/EditPageTest.php | 40 - tests/phpunit/includes/ExternalStoreTest.php | 32 - tests/phpunit/includes/ExtraParserTest.php | 169 - tests/phpunit/includes/FauxResponseTest.php | 70 - .../includes/FormOptionsInitializationTest.php | 85 - tests/phpunit/includes/FormOptionsTest.php | 90 - .../includes/GlobalFunctions/GlobalTest.php | 598 -- .../includes/GlobalFunctions/GlobalWithDBTest.php | 29 - tests/phpunit/includes/GlobalFunctions/README | 2 - .../includes/GlobalFunctions/wfAssembleUrlTest.php | 111 - .../includes/GlobalFunctions/wfBCP47Test.php | 133 - .../includes/GlobalFunctions/wfBaseNameTest.php | 36 - .../includes/GlobalFunctions/wfExpandUrlTest.php | 80 - .../includes/GlobalFunctions/wfGetCallerTest.php | 35 - .../GlobalFunctions/wfRemoveDotSegmentsTest.php | 90 - .../GlobalFunctions/wfShorthandToIntegerTest.php | 28 - .../includes/GlobalFunctions/wfTimestampTest.php | 134 - .../includes/GlobalFunctions/wfUrlencodeTest.php | 120 - tests/phpunit/includes/HooksTest.php | 102 - tests/phpunit/includes/HtmlTest.php | 580 -- tests/phpunit/includes/HttpTest.php | 180 - tests/phpunit/includes/IPTest.php | 542 - tests/phpunit/includes/JsonTest.php | 33 - tests/phpunit/includes/LanguageConverterTest.php | 130 - tests/phpunit/includes/LicensesTest.php | 22 - tests/phpunit/includes/LinksUpdateTest.php | 154 - tests/phpunit/includes/LocalFileTest.php | 108 - tests/phpunit/includes/LocalisationCacheTest.php | 31 - tests/phpunit/includes/MWFunctionTest.php | 86 - tests/phpunit/includes/MWNamespaceTest.php | 628 -- tests/phpunit/includes/MessageTest.php | 64 - tests/phpunit/includes/ParserOptionsTest.php | 35 - tests/phpunit/includes/PathRouterTest.php | 254 - tests/phpunit/includes/PreferencesTest.php | 75 - tests/phpunit/includes/Providers.php | 44 - tests/phpunit/includes/RecentChangeTest.php | 273 - tests/phpunit/includes/ResourceLoaderTest.php | 91 - tests/phpunit/includes/RevisionStorageTest.php | 408 - tests/phpunit/includes/RevisionTest.php | 125 - tests/phpunit/includes/SampleTest.php | 98 - tests/phpunit/includes/SanitizerTest.php | 162 - .../includes/SanitizerValidateEmailTest.php | 79 - .../phpunit/includes/SeleniumConfigurationTest.php | 228 - tests/phpunit/includes/SiteConfigurationTest.php | 311 - tests/phpunit/includes/TemplateCategoriesTest.php | 36 - tests/phpunit/includes/TestUser.php | 58 - tests/phpunit/includes/TimeAdjustTest.php | 51 - tests/phpunit/includes/TimestampTest.php | 72 - tests/phpunit/includes/TitleMethodsTest.php | 201 - tests/phpunit/includes/TitlePermissionTest.php | 660 -- tests/phpunit/includes/TitleTest.php | 155 - tests/phpunit/includes/UserTest.php | 171 - tests/phpunit/includes/WebRequestTest.php | 216 - tests/phpunit/includes/WikiPageTest.php | 784 -- tests/phpunit/includes/XmlJsTest.php | 9 - tests/phpunit/includes/XmlSelectTest.php | 139 - tests/phpunit/includes/XmlTest.php | 342 - tests/phpunit/includes/ZipDirectoryReaderTest.php | 79 - tests/phpunit/includes/api/ApiBlockTest.php | 117 - tests/phpunit/includes/api/ApiEditPageTest.php | 84 - tests/phpunit/includes/api/ApiOptionsTest.php | 276 - tests/phpunit/includes/api/ApiPurgeTest.php | 40 - tests/phpunit/includes/api/ApiQueryTest.php | 68 - tests/phpunit/includes/api/ApiTest.php | 280 - tests/phpunit/includes/api/ApiTestCase.php | 187 - tests/phpunit/includes/api/ApiTestCaseUpload.php | 148 - tests/phpunit/includes/api/ApiUploadTest.php | 569 - tests/phpunit/includes/api/ApiWatchTest.php | 176 - .../phpunit/includes/api/PrefixUniquenessTest.php | 24 - .../phpunit/includes/api/RandomImageGenerator.php | 463 - .../includes/api/format/ApiFormatPhpTest.php | 19 - .../includes/api/format/ApiFormatTestBase.php | 22 - .../phpunit/includes/api/generateRandomImages.php | 51 - tests/phpunit/includes/api/words.txt | 1000 -- tests/phpunit/includes/cache/GenderCacheTest.php | 101 - .../phpunit/includes/cache/ProcessCacheLRUTest.php | 239 - tests/phpunit/includes/db/DatabaseSQLTest.php | 147 - tests/phpunit/includes/db/DatabaseSqliteTest.php | 326 - tests/phpunit/includes/db/DatabaseTest.php | 215 - tests/phpunit/includes/db/ORMRowTest.php | 234 - tests/phpunit/includes/db/TestORMRowTest.php | 174 - tests/phpunit/includes/debug/MWDebugTest.php | 68 - .../phpunit/includes/filerepo/FileBackendTest.php | 1868 ---- tests/phpunit/includes/filerepo/FileRepoTest.php | 45 - tests/phpunit/includes/filerepo/StoreBatchTest.php | 123 - .../includes/installer/InstallDocFormatterTest.php | 64 - tests/phpunit/includes/json/ServicesJsonTest.php | 93 - tests/phpunit/includes/libs/CSSJanusTest.php | 560 - tests/phpunit/includes/libs/CSSMinTest.php | 142 - .../includes/libs/GenericArrayObjectTest.php | 245 - tests/phpunit/includes/libs/IEUrlExtensionTest.php | 118 - .../includes/libs/JavaScriptMinifierTest.php | 170 - .../includes/media/BitmapMetadataHandlerTest.php | 146 - tests/phpunit/includes/media/BitmapScalingTest.php | 151 - tests/phpunit/includes/media/ExifBitmapTest.php | 100 - tests/phpunit/includes/media/ExifRotationTest.php | 260 - tests/phpunit/includes/media/ExifTest.php | 48 - .../phpunit/includes/media/FormatMetadataTest.php | 52 - .../includes/media/GIFMetadataExtractorTest.php | 96 - tests/phpunit/includes/media/GIFTest.php | 98 - tests/phpunit/includes/media/IPTCTest.php | 55 - .../includes/media/JpegMetadataExtractorTest.php | 94 - tests/phpunit/includes/media/JpegTest.php | 31 - tests/phpunit/includes/media/MediaHandlerTest.php | 50 - .../includes/media/PNGMetadataExtractorTest.php | 141 - tests/phpunit/includes/media/PNGTest.php | 100 - .../includes/media/SVGMetadataExtractorTest.php | 108 - tests/phpunit/includes/media/TiffTest.php | 35 - tests/phpunit/includes/media/XMPTest.php | 158 - tests/phpunit/includes/media/XMPValidateTest.php | 47 - .../includes/mobile/DeviceDetectionTest.php | 40 - tests/phpunit/includes/normal/CleanUpTest.php | 382 - .../phpunit/includes/parser/MagicVariableTest.php | 201 - .../includes/parser/MediaWikiParserTest.php | 36 - tests/phpunit/includes/parser/NewParserTest.php | 895 -- .../phpunit/includes/parser/ParserMethodsTest.php | 33 - .../phpunit/includes/parser/ParserPreloadTest.php | 67 - tests/phpunit/includes/parser/PreprocessorTest.php | 233 - tests/phpunit/includes/parser/TagHooksTest.php | 77 - tests/phpunit/includes/search/SearchEngineTest.php | 163 - tests/phpunit/includes/search/SearchUpdateTest.php | 90 - .../includes/specials/QueryAllSpecialPagesTest.php | 79 - .../includes/specials/SpecialRecentchangesTest.php | 132 - .../includes/specials/SpecialSearchTest.php | 116 - .../phpunit/includes/upload/UploadFromUrlTest.php | 351 - tests/phpunit/includes/upload/UploadStashTest.php | 77 - tests/phpunit/includes/upload/UploadTest.php | 141 - tests/phpunit/install-phpunit.sh | 36 - tests/phpunit/languages/LanguageAmTest.php | 33 - tests/phpunit/languages/LanguageArTest.php | 78 - tests/phpunit/languages/LanguageBeTest.php | 40 - tests/phpunit/languages/LanguageBe_taraskTest.php | 65 - tests/phpunit/languages/LanguageBhTest.php | 34 - tests/phpunit/languages/LanguageBsTest.php | 41 - tests/phpunit/languages/LanguageCsTest.php | 40 - tests/phpunit/languages/LanguageCuTest.php | 41 - tests/phpunit/languages/LanguageCyTest.php | 42 - tests/phpunit/languages/LanguageDsbTest.php | 40 - tests/phpunit/languages/LanguageFrTest.php | 34 - tests/phpunit/languages/LanguageGaTest.php | 34 - tests/phpunit/languages/LanguageGdTest.php | 38 - tests/phpunit/languages/LanguageGvTest.php | 39 - tests/phpunit/languages/LanguageHeTest.php | 48 - tests/phpunit/languages/LanguageHiTest.php | 34 - tests/phpunit/languages/LanguageHrTest.php | 41 - tests/phpunit/languages/LanguageHsbTest.php | 40 - tests/phpunit/languages/LanguageHuTest.php | 34 - tests/phpunit/languages/LanguageHyTest.php | 34 - tests/phpunit/languages/LanguageKshTest.php | 34 - tests/phpunit/languages/LanguageLnTest.php | 34 - tests/phpunit/languages/LanguageLtTest.php | 53 - tests/phpunit/languages/LanguageLvTest.php | 39 - tests/phpunit/languages/LanguageMgTest.php | 35 - tests/phpunit/languages/LanguageMkTest.php | 41 - tests/phpunit/languages/LanguageMlTest.php | 43 - tests/phpunit/languages/LanguageMoTest.php | 43 - tests/phpunit/languages/LanguageMtTest.php | 72 - tests/phpunit/languages/LanguageNlTest.php | 28 - tests/phpunit/languages/LanguageNsoTest.php | 32 - tests/phpunit/languages/LanguagePlTest.php | 72 - tests/phpunit/languages/LanguageRoTest.php | 43 - tests/phpunit/languages/LanguageRuTest.php | 54 - tests/phpunit/languages/LanguageSeTest.php | 48 - tests/phpunit/languages/LanguageSgsTest.php | 66 - tests/phpunit/languages/LanguageShTest.php | 32 - tests/phpunit/languages/LanguageSkTest.php | 40 - tests/phpunit/languages/LanguageSlTest.php | 42 - tests/phpunit/languages/LanguageSmaTest.php | 48 - tests/phpunit/languages/LanguageSrTest.php | 223 - tests/phpunit/languages/LanguageTest.php | 1069 -- tests/phpunit/languages/LanguageTiTest.php | 32 - tests/phpunit/languages/LanguageTlTest.php | 32 - tests/phpunit/languages/LanguageTrTest.php | 68 - tests/phpunit/languages/LanguageUkTest.php | 54 - tests/phpunit/languages/LanguageUzTest.php | 120 - tests/phpunit/languages/LanguageWaTest.php | 32 - .../utils/CLDRPluralRuleEvaluatorTest.php | 95 - tests/phpunit/maintenance/DumpTestCase.php | 352 - tests/phpunit/maintenance/MaintenanceTest.php | 812 -- tests/phpunit/maintenance/backupPrefetchTest.php | 270 - tests/phpunit/maintenance/backupTextPassTest.php | 563 - tests/phpunit/maintenance/backup_LogTest.php | 227 - tests/phpunit/maintenance/backup_PageTest.php | 389 - tests/phpunit/maintenance/fetchTextTest.php | 243 - tests/phpunit/maintenance/getSlaveServerTest.php | 69 - tests/phpunit/phpunit.php | 107 - tests/phpunit/run-tests.bat | 1 - tests/phpunit/skins/SideBarTest.php | 209 - tests/phpunit/suite.xml | 49 - tests/phpunit/suites/ExtensionsTestSuite.php | 33 - tests/phpunit/suites/UploadFromUrlTestSuite.php | 204 - tests/qunit/.htaccess | 1 - tests/qunit/QUnitTestResources.php | 63 - tests/qunit/data/callMwLoaderTestCallback.js | 1 - tests/qunit/data/load.mock.php | 58 - tests/qunit/data/qunitOkCall.js | 2 - tests/qunit/data/styleTest.css.php | 61 - tests/qunit/data/testrunner.js | 266 - .../resources/jquery/jquery.autoEllipsis.test.js | 52 - .../resources/jquery/jquery.byteLength.test.js | 33 - .../resources/jquery/jquery.byteLimit.test.js | 234 - .../suites/resources/jquery/jquery.client.test.js | 317 - .../resources/jquery/jquery.colorUtil.test.js | 58 - .../resources/jquery/jquery.delayedBind.test.js | 35 - .../resources/jquery/jquery.getAttrs.test.js | 11 - .../resources/jquery/jquery.highlightText.test.js | 232 - .../resources/jquery/jquery.localize.test.js | 133 - .../resources/jquery/jquery.mwExtension.test.js | 58 - .../resources/jquery/jquery.tabIndex.test.js | 33 - .../resources/jquery/jquery.tablesorter.test.js | 697 -- .../resources/jquery/jquery.textSelection.test.js | 275 - .../mediawiki.api/mediawiki.api.parse.test.js | 26 - .../resources/mediawiki.api/mediawiki.api.test.js | 59 - .../mediawiki.special.recentchanges.test.js | 62 - .../resources/mediawiki/mediawiki.Title.test.js | 200 - .../resources/mediawiki/mediawiki.Uri.test.js | 388 - .../resources/mediawiki/mediawiki.cldr.test.js | 74 - .../mediawiki/mediawiki.jqueryMsg.test.js | 97 - .../resources/mediawiki/mediawiki.jscompat.test.js | 62 - .../resources/mediawiki/mediawiki.language.test.js | 394 - .../suites/resources/mediawiki/mediawiki.test.js | 649 -- .../resources/mediawiki/mediawiki.user.test.js | 56 - .../resources/mediawiki/mediawiki.util.test.js | 288 - tests/selenium/Selenium.php | 190 - tests/selenium/SeleniumConfig.php | 79 - tests/selenium/SeleniumLoader.php | 9 - tests/selenium/SeleniumServerManager.php | 239 - tests/selenium/SeleniumTestCase.php | 127 - tests/selenium/SeleniumTestConsoleLogger.php | 25 - tests/selenium/SeleniumTestConstants.php | 24 - tests/selenium/SeleniumTestHTMLLogger.php | 36 - tests/selenium/SeleniumTestListener.php | 68 - tests/selenium/SeleniumTestSuite.php | 57 - tests/selenium/data/SimpleSeleniumTestDB.sql | 1453 --- tests/selenium/data/SimpleSeleniumTestImages.zip | Bin 21993 -> 0 bytes tests/selenium/data/Wikipedia-logo-v2-de.png | Bin 21479 -> 0 bytes .../data/mediawiki118_fresh_installation.sql | 1543 --- .../MediaWikiButtonsAvailabilityTestCase.php | 102 - .../MediaWikiDifferentDatabaseAccountTestCase.php | 82 - .../MediaWikiDifferntDatabasePrefixTestCase.php | 95 - ...ediaWikiErrorsConnectToDatabasePageTestCase.php | 136 - .../installer/MediaWikiErrorsNamepageTestCase.php | 132 - .../installer/MediaWikiHelpFieldHintTestCase.php | 140 - .../MediaWikiInstallationCommonFunction.php | 283 - .../installer/MediaWikiInstallationConfig.php | 49 - .../installer/MediaWikiInstallationMessage.php | 57 - .../installer/MediaWikiInstallationVariables.php | 77 - .../installer/MediaWikiInstallerTestSuite.php | 53 - .../installer/MediaWikiMySQLDataBaseTestCase.php | 78 - .../MediaWikiMySQLiteDataBaseTestCase.php | 79 - .../MediaWikiOnAlreadyInstalledTestCase.php | 71 - .../MediaWikiRestartInstallationTestCase.php | 115 - .../MediaWikiRightFrameworkLinksTestCase.php | 93 - .../MediaWikiUpgradeExistingDatabaseTestCase.php | 117 - .../installer/MediaWikiUserInterfaceTestCase.php | 531 - tests/selenium/installer/README.txt | 32 - tests/selenium/selenium_settings.ini.sample | 32 - tests/selenium/selenium_settings_grid.ini.sample | 16 - .../suites/AddContentToNewPageTestCase.php | 182 - tests/selenium/suites/AddNewPageTestCase.php | 65 - tests/selenium/suites/CreateAccountTestCase.php | 114 - tests/selenium/suites/DeletePageAdminTestCase.php | 89 - tests/selenium/suites/EmailPasswordTestCase.php | 81 - tests/selenium/suites/MediaWikiEditorConfig.php | 48 - tests/selenium/suites/MediaWikiEditorTestSuite.php | 18 - tests/selenium/suites/MediaWikiExtraTestSuite.php | 20 - .../selenium/suites/MediawikiCoreSmokeTestCase.php | 69 - .../suites/MediawikiCoreSmokeTestSuite.php | 19 - tests/selenium/suites/MovePageTestCase.php | 117 - tests/selenium/suites/MyContributionsTestCase.php | 65 - tests/selenium/suites/MyWatchListTestCase.php | 57 - tests/selenium/suites/PageDeleteTestSuite.php | 16 - tests/selenium/suites/PageSearchTestCase.php | 105 - tests/selenium/suites/PreviewPageTestCase.php | 53 - tests/selenium/suites/SavePageTestCase.php | 58 - tests/selenium/suites/SimpleSeleniumConfig.php | 30 - tests/selenium/suites/SimpleSeleniumTestCase.php | 39 - tests/selenium/suites/SimpleSeleniumTestSuite.php | 26 - tests/selenium/suites/UserPreferencesTestCase.php | 179 - tests/testHelpers.inc | 582 -- 421 files changed, 75727 deletions(-) delete mode 100644 tests/.htaccess delete mode 100644 tests/RunSeleniumTests.php delete mode 100644 tests/TestsAutoLoader.php delete mode 100644 tests/jasmine/.htaccess delete mode 100644 tests/jasmine/SpecRunner.html delete mode 100644 tests/jasmine/lib/jasmine-1.0.1/MIT.LICENSE delete mode 100644 tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js delete mode 100644 tests/jasmine/lib/jasmine-1.0.1/jasmine.css delete mode 100644 tests/jasmine/lib/jasmine-1.0.1/jasmine.js delete mode 100644 tests/jasmine/spec/mediawiki.jqueryMsg.spec.data.js delete mode 100644 tests/jasmine/spec/mediawiki.jqueryMsg.spec.js delete mode 100644 tests/jasmine/spec_makers/makeJqueryMsgSpec.php delete mode 100644 tests/parser/README delete mode 100644 tests/parser/extraParserTests.txt delete mode 100644 tests/parser/parserTest.inc delete mode 100644 tests/parser/parserTests.txt delete mode 100644 tests/parser/parserTestsParserHook.php delete mode 100644 tests/parser/preprocess/All_system_messages.expected delete mode 100644 tests/parser/preprocess/All_system_messages.txt delete mode 100644 tests/parser/preprocess/Factorial.expected delete mode 100644 tests/parser/preprocess/Factorial.txt delete mode 100644 tests/parser/preprocess/Fundraising.expected delete mode 100644 tests/parser/preprocess/Fundraising.txt delete mode 100644 tests/parser/preprocess/QuoteQuran.expected delete mode 100644 tests/parser/preprocess/QuoteQuran.txt delete mode 100644 tests/parserTests.php delete mode 100644 tests/phpunit/Makefile delete mode 100644 tests/phpunit/MediaWikiLangTestCase.php delete mode 100644 tests/phpunit/MediaWikiPHPUnitCommand.php delete mode 100644 tests/phpunit/MediaWikiTestCase.php delete mode 100644 tests/phpunit/README delete mode 100644 tests/phpunit/StructureTest.php delete mode 100644 tests/phpunit/TODO delete mode 100644 tests/phpunit/bootstrap.php delete mode 100644 tests/phpunit/data/db/mysql/functions.sql delete mode 100644 tests/phpunit/data/db/postgres/functions.sql delete mode 100644 tests/phpunit/data/db/sqlite/tables-1.13.sql delete mode 100644 tests/phpunit/data/db/sqlite/tables-1.15.sql delete mode 100644 tests/phpunit/data/db/sqlite/tables-1.16.sql delete mode 100644 tests/phpunit/data/db/sqlite/tables-1.17.sql delete mode 100644 tests/phpunit/data/db/sqlite/tables-1.18.sql delete mode 100644 tests/phpunit/data/media/1bit-png.png delete mode 100644 tests/phpunit/data/media/80x60-2layers.xcf delete mode 100644 tests/phpunit/data/media/80x60-Greyscale.xcf delete mode 100644 tests/phpunit/data/media/80x60-RGB.xcf delete mode 100644 tests/phpunit/data/media/Animated_PNG_example_bouncing_beach_ball.png delete mode 100644 tests/phpunit/data/media/Gtk-media-play-ltr.svg delete mode 100644 tests/phpunit/data/media/Png-native-test.png delete mode 100644 tests/phpunit/data/media/QA_icon.svg delete mode 100644 tests/phpunit/data/media/README delete mode 100644 tests/phpunit/data/media/Toll_Texas_1.svg delete mode 100644 tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg delete mode 100644 tests/phpunit/data/media/Wikimedia-logo.svg delete mode 100644 tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg delete mode 100644 tests/phpunit/data/media/animated-xmp.gif delete mode 100644 tests/phpunit/data/media/animated.gif delete mode 100644 tests/phpunit/data/media/broken_exif_date.jpg delete mode 100644 tests/phpunit/data/media/exif-gps.jpg delete mode 100644 tests/phpunit/data/media/exif-user-comment.jpg delete mode 100644 tests/phpunit/data/media/greyscale-na-png.png delete mode 100644 tests/phpunit/data/media/greyscale-png.png delete mode 100644 tests/phpunit/data/media/iptc-invalid-psir.jpg delete mode 100644 tests/phpunit/data/media/iptc-timetest-invalid.jpg delete mode 100644 tests/phpunit/data/media/iptc-timetest.jpg delete mode 100644 tests/phpunit/data/media/jpeg-comment-binary.jpg delete mode 100644 tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg delete mode 100644 tests/phpunit/data/media/jpeg-comment-multiple.jpg delete mode 100644 tests/phpunit/data/media/jpeg-comment-utf.jpg delete mode 100644 tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg delete mode 100644 tests/phpunit/data/media/jpeg-iptc-good-hash.jpg delete mode 100644 tests/phpunit/data/media/jpeg-padding-even.jpg delete mode 100644 tests/phpunit/data/media/jpeg-padding-odd.jpg delete mode 100644 tests/phpunit/data/media/jpeg-xmp-alt.jpg delete mode 100644 tests/phpunit/data/media/jpeg-xmp-psir.jpg delete mode 100644 tests/phpunit/data/media/jpeg-xmp-psir.xmp delete mode 100644 tests/phpunit/data/media/landscape-plain.jpg delete mode 100644 tests/phpunit/data/media/nonanimated.gif delete mode 100644 tests/phpunit/data/media/portrait-rotated.jpg delete mode 100644 tests/phpunit/data/media/rgb-na-png.png delete mode 100644 tests/phpunit/data/media/rgb-png.png delete mode 100644 tests/phpunit/data/media/test.jpg delete mode 100644 tests/phpunit/data/media/test.tiff delete mode 100644 tests/phpunit/data/media/xmp.png delete mode 100644 tests/phpunit/data/xmp/1.result.php delete mode 100644 tests/phpunit/data/xmp/1.xmp delete mode 100644 tests/phpunit/data/xmp/2.result.php delete mode 100644 tests/phpunit/data/xmp/2.xmp delete mode 100644 tests/phpunit/data/xmp/3-invalid.result.php delete mode 100644 tests/phpunit/data/xmp/3-invalid.xmp delete mode 100644 tests/phpunit/data/xmp/3.result.php delete mode 100644 tests/phpunit/data/xmp/3.xmp delete mode 100644 tests/phpunit/data/xmp/4.result.php delete mode 100644 tests/phpunit/data/xmp/4.xmp delete mode 100644 tests/phpunit/data/xmp/5.result.php delete mode 100644 tests/phpunit/data/xmp/5.xmp delete mode 100644 tests/phpunit/data/xmp/6.result.php delete mode 100644 tests/phpunit/data/xmp/6.xmp delete mode 100644 tests/phpunit/data/xmp/7.result.php delete mode 100644 tests/phpunit/data/xmp/7.xmp delete mode 100644 tests/phpunit/data/xmp/README delete mode 100644 tests/phpunit/data/xmp/bag-for-seq.result.php delete mode 100644 tests/phpunit/data/xmp/bag-for-seq.xmp delete mode 100644 tests/phpunit/data/xmp/flash.result.php delete mode 100644 tests/phpunit/data/xmp/flash.xmp delete mode 100644 tests/phpunit/data/xmp/gps.result.php delete mode 100644 tests/phpunit/data/xmp/gps.xmp delete mode 100644 tests/phpunit/data/xmp/invalid-child-not-struct.result.php delete mode 100644 tests/phpunit/data/xmp/invalid-child-not-struct.xmp delete mode 100644 tests/phpunit/data/xmp/no-namespace.result.php delete mode 100644 tests/phpunit/data/xmp/no-namespace.xmp delete mode 100644 tests/phpunit/data/xmp/no-recognized-props.result.php delete mode 100644 tests/phpunit/data/xmp/no-recognized-props.xmp delete mode 100644 tests/phpunit/data/xmp/utf16BE.result.php delete mode 100644 tests/phpunit/data/xmp/utf16BE.xmp delete mode 100644 tests/phpunit/data/xmp/utf16LE.result.php delete mode 100644 tests/phpunit/data/xmp/utf16LE.xmp delete mode 100644 tests/phpunit/data/xmp/utf32BE.result.php delete mode 100644 tests/phpunit/data/xmp/utf32BE.xmp delete mode 100644 tests/phpunit/data/xmp/utf32LE.result.php delete mode 100644 tests/phpunit/data/xmp/utf32LE.xmp delete mode 100644 tests/phpunit/data/xmp/xmpExt.result.php delete mode 100644 tests/phpunit/data/xmp/xmpExt.xmp delete mode 100644 tests/phpunit/data/xmp/xmpExt2.xmp delete mode 100644 tests/phpunit/data/zip/cd-gap.zip delete mode 100644 tests/phpunit/data/zip/cd-truncated.zip delete mode 100644 tests/phpunit/data/zip/class-trailing-null.zip delete mode 100644 tests/phpunit/data/zip/class-trailing-slash.zip delete mode 100644 tests/phpunit/data/zip/class.zip delete mode 100644 tests/phpunit/data/zip/empty.zip delete mode 100644 tests/phpunit/data/zip/looks-like-zip64.zip delete mode 100644 tests/phpunit/data/zip/nosig.zip delete mode 100644 tests/phpunit/data/zip/split.zip delete mode 100644 tests/phpunit/data/zip/trail.zip delete mode 100644 tests/phpunit/data/zip/wrong-cd-start-disk.zip delete mode 100644 tests/phpunit/data/zip/wrong-central-entry-sig.zip delete mode 100644 tests/phpunit/docs/ExportDemoTest.php delete mode 100644 tests/phpunit/includes/ArticleTablesTest.php delete mode 100644 tests/phpunit/includes/ArticleTest.php delete mode 100644 tests/phpunit/includes/BlockTest.php delete mode 100644 tests/phpunit/includes/CdbTest.php delete mode 100644 tests/phpunit/includes/DiffHistoryBlobTest.php delete mode 100644 tests/phpunit/includes/EditPageTest.php delete mode 100644 tests/phpunit/includes/ExternalStoreTest.php delete mode 100644 tests/phpunit/includes/ExtraParserTest.php delete mode 100644 tests/phpunit/includes/FauxResponseTest.php delete mode 100644 tests/phpunit/includes/FormOptionsInitializationTest.php delete mode 100644 tests/phpunit/includes/FormOptionsTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/GlobalTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/README delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php delete mode 100644 tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php delete mode 100644 tests/phpunit/includes/HooksTest.php delete mode 100644 tests/phpunit/includes/HtmlTest.php delete mode 100644 tests/phpunit/includes/HttpTest.php delete mode 100644 tests/phpunit/includes/IPTest.php delete mode 100644 tests/phpunit/includes/JsonTest.php delete mode 100644 tests/phpunit/includes/LanguageConverterTest.php delete mode 100644 tests/phpunit/includes/LicensesTest.php delete mode 100644 tests/phpunit/includes/LinksUpdateTest.php delete mode 100644 tests/phpunit/includes/LocalFileTest.php delete mode 100644 tests/phpunit/includes/LocalisationCacheTest.php delete mode 100644 tests/phpunit/includes/MWFunctionTest.php delete mode 100644 tests/phpunit/includes/MWNamespaceTest.php delete mode 100644 tests/phpunit/includes/MessageTest.php delete mode 100644 tests/phpunit/includes/ParserOptionsTest.php delete mode 100644 tests/phpunit/includes/PathRouterTest.php delete mode 100644 tests/phpunit/includes/PreferencesTest.php delete mode 100644 tests/phpunit/includes/Providers.php delete mode 100644 tests/phpunit/includes/RecentChangeTest.php delete mode 100644 tests/phpunit/includes/ResourceLoaderTest.php delete mode 100644 tests/phpunit/includes/RevisionStorageTest.php delete mode 100644 tests/phpunit/includes/RevisionTest.php delete mode 100644 tests/phpunit/includes/SampleTest.php delete mode 100644 tests/phpunit/includes/SanitizerTest.php delete mode 100644 tests/phpunit/includes/SanitizerValidateEmailTest.php delete mode 100644 tests/phpunit/includes/SeleniumConfigurationTest.php delete mode 100644 tests/phpunit/includes/SiteConfigurationTest.php delete mode 100644 tests/phpunit/includes/TemplateCategoriesTest.php delete mode 100644 tests/phpunit/includes/TestUser.php delete mode 100644 tests/phpunit/includes/TimeAdjustTest.php delete mode 100644 tests/phpunit/includes/TimestampTest.php delete mode 100644 tests/phpunit/includes/TitleMethodsTest.php delete mode 100644 tests/phpunit/includes/TitlePermissionTest.php delete mode 100644 tests/phpunit/includes/TitleTest.php delete mode 100644 tests/phpunit/includes/UserTest.php delete mode 100644 tests/phpunit/includes/WebRequestTest.php delete mode 100644 tests/phpunit/includes/WikiPageTest.php delete mode 100644 tests/phpunit/includes/XmlJsTest.php delete mode 100644 tests/phpunit/includes/XmlSelectTest.php delete mode 100644 tests/phpunit/includes/XmlTest.php delete mode 100644 tests/phpunit/includes/ZipDirectoryReaderTest.php delete mode 100644 tests/phpunit/includes/api/ApiBlockTest.php delete mode 100644 tests/phpunit/includes/api/ApiEditPageTest.php delete mode 100644 tests/phpunit/includes/api/ApiOptionsTest.php delete mode 100644 tests/phpunit/includes/api/ApiPurgeTest.php delete mode 100644 tests/phpunit/includes/api/ApiQueryTest.php delete mode 100644 tests/phpunit/includes/api/ApiTest.php delete mode 100644 tests/phpunit/includes/api/ApiTestCase.php delete mode 100644 tests/phpunit/includes/api/ApiTestCaseUpload.php delete mode 100644 tests/phpunit/includes/api/ApiUploadTest.php delete mode 100644 tests/phpunit/includes/api/ApiWatchTest.php delete mode 100644 tests/phpunit/includes/api/PrefixUniquenessTest.php delete mode 100644 tests/phpunit/includes/api/RandomImageGenerator.php delete mode 100644 tests/phpunit/includes/api/format/ApiFormatPhpTest.php delete mode 100644 tests/phpunit/includes/api/format/ApiFormatTestBase.php delete mode 100644 tests/phpunit/includes/api/generateRandomImages.php delete mode 100644 tests/phpunit/includes/api/words.txt delete mode 100644 tests/phpunit/includes/cache/GenderCacheTest.php delete mode 100644 tests/phpunit/includes/cache/ProcessCacheLRUTest.php delete mode 100644 tests/phpunit/includes/db/DatabaseSQLTest.php delete mode 100644 tests/phpunit/includes/db/DatabaseSqliteTest.php delete mode 100644 tests/phpunit/includes/db/DatabaseTest.php delete mode 100644 tests/phpunit/includes/db/ORMRowTest.php delete mode 100644 tests/phpunit/includes/db/TestORMRowTest.php delete mode 100644 tests/phpunit/includes/debug/MWDebugTest.php delete mode 100644 tests/phpunit/includes/filerepo/FileBackendTest.php delete mode 100644 tests/phpunit/includes/filerepo/FileRepoTest.php delete mode 100644 tests/phpunit/includes/filerepo/StoreBatchTest.php delete mode 100644 tests/phpunit/includes/installer/InstallDocFormatterTest.php delete mode 100644 tests/phpunit/includes/json/ServicesJsonTest.php delete mode 100644 tests/phpunit/includes/libs/CSSJanusTest.php delete mode 100644 tests/phpunit/includes/libs/CSSMinTest.php delete mode 100644 tests/phpunit/includes/libs/GenericArrayObjectTest.php delete mode 100644 tests/phpunit/includes/libs/IEUrlExtensionTest.php delete mode 100644 tests/phpunit/includes/libs/JavaScriptMinifierTest.php delete mode 100644 tests/phpunit/includes/media/BitmapMetadataHandlerTest.php delete mode 100644 tests/phpunit/includes/media/BitmapScalingTest.php delete mode 100644 tests/phpunit/includes/media/ExifBitmapTest.php delete mode 100644 tests/phpunit/includes/media/ExifRotationTest.php delete mode 100644 tests/phpunit/includes/media/ExifTest.php delete mode 100644 tests/phpunit/includes/media/FormatMetadataTest.php delete mode 100644 tests/phpunit/includes/media/GIFMetadataExtractorTest.php delete mode 100644 tests/phpunit/includes/media/GIFTest.php delete mode 100644 tests/phpunit/includes/media/IPTCTest.php delete mode 100644 tests/phpunit/includes/media/JpegMetadataExtractorTest.php delete mode 100644 tests/phpunit/includes/media/JpegTest.php delete mode 100644 tests/phpunit/includes/media/MediaHandlerTest.php delete mode 100644 tests/phpunit/includes/media/PNGMetadataExtractorTest.php delete mode 100644 tests/phpunit/includes/media/PNGTest.php delete mode 100644 tests/phpunit/includes/media/SVGMetadataExtractorTest.php delete mode 100644 tests/phpunit/includes/media/TiffTest.php delete mode 100644 tests/phpunit/includes/media/XMPTest.php delete mode 100644 tests/phpunit/includes/media/XMPValidateTest.php delete mode 100644 tests/phpunit/includes/mobile/DeviceDetectionTest.php delete mode 100644 tests/phpunit/includes/normal/CleanUpTest.php delete mode 100644 tests/phpunit/includes/parser/MagicVariableTest.php delete mode 100644 tests/phpunit/includes/parser/MediaWikiParserTest.php delete mode 100644 tests/phpunit/includes/parser/NewParserTest.php delete mode 100644 tests/phpunit/includes/parser/ParserMethodsTest.php delete mode 100644 tests/phpunit/includes/parser/ParserPreloadTest.php delete mode 100644 tests/phpunit/includes/parser/PreprocessorTest.php delete mode 100644 tests/phpunit/includes/parser/TagHooksTest.php delete mode 100644 tests/phpunit/includes/search/SearchEngineTest.php delete mode 100644 tests/phpunit/includes/search/SearchUpdateTest.php delete mode 100644 tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php delete mode 100644 tests/phpunit/includes/specials/SpecialRecentchangesTest.php delete mode 100644 tests/phpunit/includes/specials/SpecialSearchTest.php delete mode 100644 tests/phpunit/includes/upload/UploadFromUrlTest.php delete mode 100644 tests/phpunit/includes/upload/UploadStashTest.php delete mode 100644 tests/phpunit/includes/upload/UploadTest.php delete mode 100644 tests/phpunit/install-phpunit.sh delete mode 100644 tests/phpunit/languages/LanguageAmTest.php delete mode 100644 tests/phpunit/languages/LanguageArTest.php delete mode 100644 tests/phpunit/languages/LanguageBeTest.php delete mode 100644 tests/phpunit/languages/LanguageBe_taraskTest.php delete mode 100644 tests/phpunit/languages/LanguageBhTest.php delete mode 100644 tests/phpunit/languages/LanguageBsTest.php delete mode 100644 tests/phpunit/languages/LanguageCsTest.php delete mode 100644 tests/phpunit/languages/LanguageCuTest.php delete mode 100644 tests/phpunit/languages/LanguageCyTest.php delete mode 100644 tests/phpunit/languages/LanguageDsbTest.php delete mode 100644 tests/phpunit/languages/LanguageFrTest.php delete mode 100644 tests/phpunit/languages/LanguageGaTest.php delete mode 100644 tests/phpunit/languages/LanguageGdTest.php delete mode 100644 tests/phpunit/languages/LanguageGvTest.php delete mode 100644 tests/phpunit/languages/LanguageHeTest.php delete mode 100644 tests/phpunit/languages/LanguageHiTest.php delete mode 100644 tests/phpunit/languages/LanguageHrTest.php delete mode 100644 tests/phpunit/languages/LanguageHsbTest.php delete mode 100644 tests/phpunit/languages/LanguageHuTest.php delete mode 100644 tests/phpunit/languages/LanguageHyTest.php delete mode 100644 tests/phpunit/languages/LanguageKshTest.php delete mode 100644 tests/phpunit/languages/LanguageLnTest.php delete mode 100644 tests/phpunit/languages/LanguageLtTest.php delete mode 100644 tests/phpunit/languages/LanguageLvTest.php delete mode 100644 tests/phpunit/languages/LanguageMgTest.php delete mode 100644 tests/phpunit/languages/LanguageMkTest.php delete mode 100644 tests/phpunit/languages/LanguageMlTest.php delete mode 100644 tests/phpunit/languages/LanguageMoTest.php delete mode 100644 tests/phpunit/languages/LanguageMtTest.php delete mode 100644 tests/phpunit/languages/LanguageNlTest.php delete mode 100644 tests/phpunit/languages/LanguageNsoTest.php delete mode 100644 tests/phpunit/languages/LanguagePlTest.php delete mode 100644 tests/phpunit/languages/LanguageRoTest.php delete mode 100644 tests/phpunit/languages/LanguageRuTest.php delete mode 100644 tests/phpunit/languages/LanguageSeTest.php delete mode 100644 tests/phpunit/languages/LanguageSgsTest.php delete mode 100644 tests/phpunit/languages/LanguageShTest.php delete mode 100644 tests/phpunit/languages/LanguageSkTest.php delete mode 100644 tests/phpunit/languages/LanguageSlTest.php delete mode 100644 tests/phpunit/languages/LanguageSmaTest.php delete mode 100644 tests/phpunit/languages/LanguageSrTest.php delete mode 100644 tests/phpunit/languages/LanguageTest.php delete mode 100644 tests/phpunit/languages/LanguageTiTest.php delete mode 100644 tests/phpunit/languages/LanguageTlTest.php delete mode 100644 tests/phpunit/languages/LanguageTrTest.php delete mode 100644 tests/phpunit/languages/LanguageUkTest.php delete mode 100644 tests/phpunit/languages/LanguageUzTest.php delete mode 100644 tests/phpunit/languages/LanguageWaTest.php delete mode 100644 tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php delete mode 100644 tests/phpunit/maintenance/DumpTestCase.php delete mode 100644 tests/phpunit/maintenance/MaintenanceTest.php delete mode 100644 tests/phpunit/maintenance/backupPrefetchTest.php delete mode 100644 tests/phpunit/maintenance/backupTextPassTest.php delete mode 100644 tests/phpunit/maintenance/backup_LogTest.php delete mode 100644 tests/phpunit/maintenance/backup_PageTest.php delete mode 100644 tests/phpunit/maintenance/fetchTextTest.php delete mode 100644 tests/phpunit/maintenance/getSlaveServerTest.php delete mode 100644 tests/phpunit/phpunit.php delete mode 100644 tests/phpunit/run-tests.bat delete mode 100644 tests/phpunit/skins/SideBarTest.php delete mode 100644 tests/phpunit/suite.xml delete mode 100644 tests/phpunit/suites/ExtensionsTestSuite.php delete mode 100644 tests/phpunit/suites/UploadFromUrlTestSuite.php delete mode 100644 tests/qunit/.htaccess delete mode 100644 tests/qunit/QUnitTestResources.php delete mode 100644 tests/qunit/data/callMwLoaderTestCallback.js delete mode 100644 tests/qunit/data/load.mock.php delete mode 100644 tests/qunit/data/qunitOkCall.js delete mode 100644 tests/qunit/data/styleTest.css.php delete mode 100644 tests/qunit/data/testrunner.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.byteLength.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.client.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.highlightText.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.localize.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js delete mode 100644 tests/qunit/suites/resources/jquery/jquery.textSelection.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js delete mode 100644 tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js delete mode 100644 tests/selenium/Selenium.php delete mode 100644 tests/selenium/SeleniumConfig.php delete mode 100644 tests/selenium/SeleniumLoader.php delete mode 100644 tests/selenium/SeleniumServerManager.php delete mode 100644 tests/selenium/SeleniumTestCase.php delete mode 100644 tests/selenium/SeleniumTestConsoleLogger.php delete mode 100644 tests/selenium/SeleniumTestConstants.php delete mode 100644 tests/selenium/SeleniumTestHTMLLogger.php delete mode 100644 tests/selenium/SeleniumTestListener.php delete mode 100644 tests/selenium/SeleniumTestSuite.php delete mode 100644 tests/selenium/data/SimpleSeleniumTestDB.sql delete mode 100644 tests/selenium/data/SimpleSeleniumTestImages.zip delete mode 100644 tests/selenium/data/Wikipedia-logo-v2-de.png delete mode 100644 tests/selenium/data/mediawiki118_fresh_installation.sql delete mode 100644 tests/selenium/installer/MediaWikiButtonsAvailabilityTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiDifferentDatabaseAccountTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiDifferntDatabasePrefixTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiErrorsConnectToDatabasePageTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiErrorsNamepageTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiHelpFieldHintTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiInstallationCommonFunction.php delete mode 100644 tests/selenium/installer/MediaWikiInstallationConfig.php delete mode 100644 tests/selenium/installer/MediaWikiInstallationMessage.php delete mode 100644 tests/selenium/installer/MediaWikiInstallationVariables.php delete mode 100644 tests/selenium/installer/MediaWikiInstallerTestSuite.php delete mode 100644 tests/selenium/installer/MediaWikiMySQLDataBaseTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiMySQLiteDataBaseTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiOnAlreadyInstalledTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiRestartInstallationTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiRightFrameworkLinksTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiUpgradeExistingDatabaseTestCase.php delete mode 100644 tests/selenium/installer/MediaWikiUserInterfaceTestCase.php delete mode 100644 tests/selenium/installer/README.txt delete mode 100644 tests/selenium/selenium_settings.ini.sample delete mode 100644 tests/selenium/selenium_settings_grid.ini.sample delete mode 100644 tests/selenium/suites/AddContentToNewPageTestCase.php delete mode 100644 tests/selenium/suites/AddNewPageTestCase.php delete mode 100644 tests/selenium/suites/CreateAccountTestCase.php delete mode 100644 tests/selenium/suites/DeletePageAdminTestCase.php delete mode 100644 tests/selenium/suites/EmailPasswordTestCase.php delete mode 100644 tests/selenium/suites/MediaWikiEditorConfig.php delete mode 100644 tests/selenium/suites/MediaWikiEditorTestSuite.php delete mode 100644 tests/selenium/suites/MediaWikiExtraTestSuite.php delete mode 100644 tests/selenium/suites/MediawikiCoreSmokeTestCase.php delete mode 100644 tests/selenium/suites/MediawikiCoreSmokeTestSuite.php delete mode 100644 tests/selenium/suites/MovePageTestCase.php delete mode 100644 tests/selenium/suites/MyContributionsTestCase.php delete mode 100644 tests/selenium/suites/MyWatchListTestCase.php delete mode 100644 tests/selenium/suites/PageDeleteTestSuite.php delete mode 100644 tests/selenium/suites/PageSearchTestCase.php delete mode 100644 tests/selenium/suites/PreviewPageTestCase.php delete mode 100644 tests/selenium/suites/SavePageTestCase.php delete mode 100644 tests/selenium/suites/SimpleSeleniumConfig.php delete mode 100644 tests/selenium/suites/SimpleSeleniumTestCase.php delete mode 100644 tests/selenium/suites/SimpleSeleniumTestSuite.php delete mode 100644 tests/selenium/suites/UserPreferencesTestCase.php delete mode 100644 tests/testHelpers.inc (limited to 'tests') diff --git a/tests/.htaccess b/tests/.htaccess deleted file mode 100644 index 3a428827..00000000 --- a/tests/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Deny from all diff --git a/tests/RunSeleniumTests.php b/tests/RunSeleniumTests.php deleted file mode 100644 index 28501eaa..00000000 --- a/tests/RunSeleniumTests.php +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/php -=' ) ) { - # PHPUnit 3.5.0 introduced a nice autoloader based on class name - require_once( 'PHPUnit/Autoload.php' ); -} else { - # Keep the old pre PHPUnit 3.5.0 behaviour for compatibility - require_once( 'PHPUnit/TextUI/Command.php' ); -} - -require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); -include_once( 'PHPUnit/Util/Log/JUnit.php' ); - -require_once( __DIR__ . "/selenium/SeleniumServerManager.php" ); - -class SeleniumTester extends Maintenance { - protected $selenium; - protected $serverManager; - protected $seleniumServerExecPath; - - public function __construct() { - parent::__construct(); - $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework"; - $this->addOption( 'port', 'Port used by selenium server. Default: 4444', false, true ); - $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath', false, true ); - $this->addOption( 'testBrowser', 'The browser used during testing. Default: firefox', false, true ); - $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost', false, true ); - $this->addOption( 'username', 'The login username for sunning tests. Default: empty', false, true ); - $this->addOption( 'userPassword', 'The login password for running tests. Default: empty', false, true ); - $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty', false, true ); - $this->addOption( 'list-browsers', 'List the available browsers.' ); - $this->addOption( 'verbose', 'Be noisier.' ); - $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' ); - $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' ); - $this->addOption( 'jUnitLogFile', 'Log results in a specified JUnit log file. Default: empty', false, true ); - $this->addOption( 'runAgainstGrid', 'The test will be run against a Selenium Grid. Default: false.', false, true ); - $this->deleteOption( 'dbpass' ); - $this->deleteOption( 'dbuser' ); - $this->deleteOption( 'globals' ); - $this->deleteOption( 'wiki' ); - } - - public function listBrowsers() { - $desc = "Available browsers:\n"; - - foreach ($this->selenium->getAvailableBrowsers() as $k => $v) { - $desc .= " $k => $v\n"; - } - - echo $desc; - } - - protected function startServer() { - if ( $this->seleniumServerExecPath == '' ) { - die ( "The selenium server exec path is not set in " . - "selenium_settings.ini. Cannot start server \n" . - "as requested - terminating RunSeleniumTests\n" ); - } - $this->serverManager = new SeleniumServerManager( 'true', - $this->selenium->getPort(), - $this->seleniumServerExecPath ); - switch ( $this->serverManager->start() ) { - case 'started': - break; - case 'failed': - die ( "Unable to start the Selenium Server - " . - "terminating RunSeleniumTests\n" ); - case 'running': - echo ( "Warning: The Selenium Server is " . - "already running\n" ); - break; - } - - return; - } - - protected function stopServer() { - if ( !isset ( $this->serverManager ) ) { - echo ( "Warning: Request to stop Selenium Server, but it was " . - "not stared by RunSeleniumTests\n" . - "RunSeleniumTests cannot stop a Selenium Server it " . - "did not start\n" ); - } else { - switch ( $this->serverManager->stop() ) { - case 'stopped': - break; - case 'failed': - echo ( "unable to stop the Selenium Server\n" ); - } - } - return; - } - - protected function runTests( $seleniumTestSuites = array() ) { - $result = new PHPUnit_Framework_TestResult; - $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) ); - if ( $this->selenium->getJUnitLogFile() ) { - $jUnitListener = new PHPUnit_Util_Log_JUnit( $this->selenium->getJUnitLogFile(), true ); - $result->addListener( $jUnitListener ); - } - - foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) { - require( $testSuiteFile ); - $suite = new $testSuiteName(); - $suite->setName( $testSuiteName ); - $suite->addTests(); - - try { - $suite->run( $result ); - } catch ( Testing_Selenium_Exception $e ) { - $suite->tearDown(); - throw new MWException( $e->getMessage() ); - } - } - - if ( $this->selenium->getJUnitLogFile() ) { - $jUnitListener->flush(); - } - } - - public function execute() { - global $wgServer, $wgScriptPath, $wgHooks; - - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - - $configFile = $this->getOption( 'seleniumConfig', '' ); - if ( strlen( $configFile ) > 0 ) { - $this->output("Using Selenium Configuration file: " . $configFile . "\n"); - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - $configFile ); - } elseif ( !isset( $wgHooks['SeleniumSettings'] ) ) { - $this->output("No command line, configuration file or configuration hook found.\n"); - SeleniumConfig::getSeleniumSettings( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites - ); - } else { - $this->output("Using 'SeleniumSettings' hook for configuration.\n"); - wfRunHooks('SeleniumSettings', array( $seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites ) ); - } - - // State for starting/stopping the Selenium server has nothing to do with the Selenium - // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but - // the Maintenance class does not have a setOption() - if ( ! isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true ); - if ( ! isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true ); - if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = ''; - $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath']; - - //set reasonable defaults if we did not find the settings - if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox'); - if ( !isset( $seleniumSettings['host'] ) ) $seleniumSettings['host'] = $wgServer . $wgScriptPath; - if ( !isset( $seleniumSettings['port'] ) ) $seleniumSettings['port'] = '4444'; - if ( !isset( $seleniumSettings['wikiUrl'] ) ) $seleniumSettings['wikiUrl'] = 'http://localhost'; - if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = ''; - if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = ''; - if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox'; - if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) $seleniumSettings['jUnitLogFile'] = false; - if ( !isset( $seleniumSettings['runAgainstGrid'] ) ) $seleniumSettings['runAgainstGrid'] = false; - - // Setup Selenium class - $this->selenium = new Selenium( ); - $this->selenium->setAvailableBrowsers( $seleniumBrowsers ); - $this->selenium->setRunAgainstGrid( $this->getOption( 'runAgainstGrid', $seleniumSettings['runAgainstGrid'] ) ); - $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) ); - $this->selenium->setBrowser( $this->getOption( 'testBrowser', $seleniumSettings['testBrowser'] ) ); - $this->selenium->setPort( $this->getOption( 'port', $seleniumSettings['port'] ) ); - $this->selenium->setHost( $this->getOption( 'host', $seleniumSettings['host'] ) ); - $this->selenium->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) ); - $this->selenium->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) ); - $this->selenium->setVerbose( $this->hasOption( 'verbose' ) ); - $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) ); - - if( $this->hasOption( 'list-browsers' ) ) { - $this->listBrowsers(); - exit(0); - } - if ( $this->hasOption( 'startserver' ) ) { - $this->startServer(); - } - - $logger = new SeleniumTestConsoleLogger; - $this->selenium->setLogger( $logger ); - - $this->runTests( $seleniumTestSuites ); - - if ( $this->hasOption( 'stopserver' ) ) { - $this->stopServer(); - } - } -} - -$maintClass = "SeleniumTester"; - -require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php deleted file mode 100644 index 42f5f68a..00000000 --- a/tests/TestsAutoLoader.php +++ /dev/null @@ -1,35 +0,0 @@ - "$testFolder/phpunit/MediaWikiTestCase.php", - 'MediaWikiPHPUnitCommand' => "$testFolder/phpunit/MediaWikiPHPUnitCommand.php", - 'MediaWikiLangTestCase' => "$testFolder/phpunit/MediaWikiLangTestCase.php", - 'NewParserTest' => "$testFolder/phpunit/includes/parser/NewParserTest.php", - - //includes - 'BlockTest' => "$testFolder/phpunit/includes/BlockTest.php", - - //API - 'ApiFormatTestBase' => "$testFolder/phpunit/includes/api/format/ApiFormatTestBase.php", - 'ApiTestCase' => "$testFolder/phpunit/includes/api/ApiTestCase.php", - 'TestUser' => "$testFolder/phpunit/includes/TestUser.php", - 'MockApi' => "$testFolder/phpunit/includes/api/ApiTestCase.php", - 'RandomImageGenerator' => "$testFolder/phpunit/includes/api/RandomImageGenerator.php", - 'UserWrapper' => "$testFolder/phpunit/includes/api/ApiTestCase.php", - - //Selenium - 'SeleniumTestConstants' => "$testFolder/selenium/SeleniumTestConstants.php", - - //maintenance - 'DumpTestCase' => "$testFolder/phpunit/maintenance/DumpTestCase.php", - 'BackupDumper' => "$testFolder/../maintenance/backup.inc", - - //Generic providers - 'MediaWikiProvide' => "$testFolder/phpunit/includes/Providers.php", -); - diff --git a/tests/jasmine/.htaccess b/tests/jasmine/.htaccess deleted file mode 100644 index 605d2f4c..00000000 --- a/tests/jasmine/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Allow from all diff --git a/tests/jasmine/SpecRunner.html b/tests/jasmine/SpecRunner.html deleted file mode 100644 index 63d0fdfa..00000000 --- a/tests/jasmine/SpecRunner.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - Jasmine Test Runner - - - - - - - - - - - - - - - - - - - diff --git a/tests/jasmine/lib/jasmine-1.0.1/MIT.LICENSE b/tests/jasmine/lib/jasmine-1.0.1/MIT.LICENSE deleted file mode 100644 index 1eb9b49e..00000000 --- a/tests/jasmine/lib/jasmine-1.0.1/MIT.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2010 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js b/tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js deleted file mode 100644 index 81402b9c..00000000 --- a/tests/jasmine/lib/jasmine-1.0.1/jasmine-html.js +++ /dev/null @@ -1,188 +0,0 @@ -jasmine.TrivialReporter = function(doc) { - this.document = doc || document; - this.suiteDivs = {}; - this.logRunningSpecs = false; -}; - -jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { el.appendChild(child); } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { - var showPassed, showSkipped; - - this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, - this.createDom('div', { className: 'banner' }, - this.createDom('div', { className: 'logo' }, - this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"), - this.createDom('span', { className: 'version' }, runner.env.versionString())), - this.createDom('div', { className: 'options' }, - "Show ", - showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), - showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), - this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") - ) - ), - - this.runnerDiv = this.createDom('div', { className: 'runner running' }, - this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), - this.runnerMessageSpan = this.createDom('span', {}, "Running..."), - this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) - ); - - this.document.body.appendChild(this.outerDiv); - - var suites = runner.suites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - var suiteDiv = this.createDom('div', { className: 'suite' }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), - this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); - this.suiteDivs[suite.id] = suiteDiv; - var parentDiv = this.outerDiv; - if (suite.parentSuite) { - parentDiv = this.suiteDivs[suite.parentSuite.id]; - } - parentDiv.appendChild(suiteDiv); - } - - this.startedAt = new Date(); - - var self = this; - showPassed.onclick = function(evt) { - if (showPassed.checked) { - self.outerDiv.className += ' show-passed'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); - } - }; - - showSkipped.onclick = function(evt) { - if (showSkipped.checked) { - self.outerDiv.className += ' show-skipped'; - } else { - self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); - } - }; -}; - -jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { - var results = runner.results(); - var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; - this.runnerDiv.setAttribute("class", className); - //do it twice for IE - this.runnerDiv.setAttribute("className", className); - var specs = runner.specs(); - var specCount = 0; - for (var i = 0; i < specs.length; i++) { - if (this.specFilter(specs[i])) { - specCount++; - } - } - var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); - message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; - this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); - - this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); -}; - -jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { - var results = suite.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.totalCount == 0) { // todo: change this to check results.skipped - status = 'skipped'; - } - this.suiteDivs[suite.id].className += " " + status; -}; - -jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { - if (this.logRunningSpecs) { - this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); - } -}; - -jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { - var results = spec.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - var specDiv = this.createDom('div', { className: 'spec ' + status }, - this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), - this.createDom('a', { - className: 'description', - href: '?spec=' + encodeURIComponent(spec.getFullName()), - title: spec.getFullName() - }, spec.description)); - - - var resultItems = results.getItems(); - var messagesDiv = this.createDom('div', { className: 'messages' }); - for (var i = 0; i < resultItems.length; i++) { - var result = resultItems[i]; - - if (result.type == 'log') { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); - } else if (result.type == 'expect' && result.passed && !result.passed()) { - messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); - - if (result.trace.stack) { - messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); - } - } - } - - if (messagesDiv.childNodes.length > 0) { - specDiv.appendChild(messagesDiv); - } - - this.suiteDivs[spec.suite.id].appendChild(specDiv); -}; - -jasmine.TrivialReporter.prototype.log = function() { - var console = jasmine.getGlobal().console; - if (console && console.log) { - if (console.log.apply) { - console.log.apply(console, arguments); - } else { - console.log(arguments); // ie fix: console.log.apply doesn't exist on ie - } - } -}; - -jasmine.TrivialReporter.prototype.getLocation = function() { - return this.document.location; -}; - -jasmine.TrivialReporter.prototype.specFilter = function(spec) { - var paramMap = {}; - var params = this.getLocation().search.substring(1).split('&'); - for (var i = 0; i < params.length; i++) { - var p = params[i].split('='); - paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); - } - - if (!paramMap["spec"]) return true; - return spec.getFullName().indexOf(paramMap["spec"]) == 0; -}; diff --git a/tests/jasmine/lib/jasmine-1.0.1/jasmine.css b/tests/jasmine/lib/jasmine-1.0.1/jasmine.css deleted file mode 100644 index 6583fe7c..00000000 --- a/tests/jasmine/lib/jasmine-1.0.1/jasmine.css +++ /dev/null @@ -1,166 +0,0 @@ -body { - font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; -} - - -.jasmine_reporter a:visited, .jasmine_reporter a { - color: #303; -} - -.jasmine_reporter a:hover, .jasmine_reporter a:active { - color: blue; -} - -.run_spec { - float:right; - padding-right: 5px; - font-size: .8em; - text-decoration: none; -} - -.jasmine_reporter { - margin: 0 5px; -} - -.banner { - color: #303; - background-color: #fef; - padding: 5px; -} - -.logo { - float: left; - font-size: 1.1em; - padding-left: 5px; -} - -.logo .version { - font-size: .6em; - padding-left: 1em; -} - -.runner.running { - background-color: yellow; -} - - -.options { - text-align: right; - font-size: .8em; -} - - - - -.suite { - border: 1px outset gray; - margin: 5px 0; - padding-left: 1em; -} - -.suite .suite { - margin: 5px; -} - -.suite.passed { - background-color: #dfd; -} - -.suite.failed { - background-color: #fdd; -} - -.spec { - margin: 5px; - padding-left: 1em; - clear: both; -} - -.spec.failed, .spec.passed, .spec.skipped { - padding-bottom: 5px; - border: 1px solid gray; -} - -.spec.failed { - background-color: #fbb; - border-color: red; -} - -.spec.passed { - background-color: #bfb; - border-color: green; -} - -.spec.skipped { - background-color: #bbb; -} - -.messages { - border-left: 1px dashed gray; - padding-left: 1em; - padding-right: 1em; -} - -.passed { - background-color: #cfc; - display: none; -} - -.failed { - background-color: #fbb; -} - -.skipped { - color: #777; - background-color: #eee; - display: none; -} - - -/*.resultMessage {*/ - /*white-space: pre;*/ -/*}*/ - -.resultMessage span.result { - display: block; - line-height: 2em; - color: black; -} - -.resultMessage .mismatch { - color: black; -} - -.stackTrace { - white-space: pre; - font-size: .8em; - margin-left: 10px; - max-height: 5em; - overflow: auto; - border: 1px inset red; - padding: 1em; - background: #eef; -} - -.finished-at { - padding-left: 1em; - font-size: .6em; -} - -.show-passed .passed, -.show-skipped .skipped { - display: block; -} - - -#jasmine_content { - position:fixed; - right: 100%; -} - -.runner { - border: 1px solid gray; - display: block; - margin: 5px 0; - padding: 2px 0 2px 10px; -} diff --git a/tests/jasmine/lib/jasmine-1.0.1/jasmine.js b/tests/jasmine/lib/jasmine-1.0.1/jasmine.js deleted file mode 100644 index 964f99ed..00000000 --- a/tests/jasmine/lib/jasmine-1.0.1/jasmine.js +++ /dev/null @@ -1,2421 +0,0 @@ -/** - * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. - * - * @namespace - */ -var jasmine = {}; - -/** - * @private - */ -jasmine.unimplementedMethod_ = function() { - throw new Error("unimplemented method"); -}; - -/** - * Use jasmine.undefined instead of undefined, since undefined is just - * a plain old variable and may be redefined by somebody else. - * - * @private - */ -jasmine.undefined = jasmine.___undefined___; - -/** - * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. - * - */ -jasmine.DEFAULT_UPDATE_INTERVAL = 250; - -/** - * Default timeout interval in milliseconds for waitsFor() blocks. - */ -jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; - -jasmine.getGlobal = function() { - function getGlobal() { - return this; - } - - return getGlobal(); -}; - -/** - * Allows for bound functions to be compared. Internal use only. - * - * @ignore - * @private - * @param base {Object} bound 'this' for the function - * @param name {Function} function to find - */ -jasmine.bindOriginal_ = function(base, name) { - var original = base[name]; - if (original.apply) { - return function() { - return original.apply(base, arguments); - }; - } else { - // IE support - return jasmine.getGlobal()[name]; - } -}; - -jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); -jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); -jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); -jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); - -jasmine.MessageResult = function(values) { - this.type = 'log'; - this.values = values; - this.trace = new Error(); // todo: test better -}; - -jasmine.MessageResult.prototype.toString = function() { - var text = ""; - for(var i = 0; i < this.values.length; i++) { - if (i > 0) text += " "; - if (jasmine.isString_(this.values[i])) { - text += this.values[i]; - } else { - text += jasmine.pp(this.values[i]); - } - } - return text; -}; - -jasmine.ExpectationResult = function(params) { - this.type = 'expect'; - this.matcherName = params.matcherName; - this.passed_ = params.passed; - this.expected = params.expected; - this.actual = params.actual; - - this.message = this.passed_ ? 'Passed.' : params.message; - this.trace = this.passed_ ? '' : new Error(this.message); -}; - -jasmine.ExpectationResult.prototype.toString = function () { - return this.message; -}; - -jasmine.ExpectationResult.prototype.passed = function () { - return this.passed_; -}; - -/** - * Getter for the Jasmine environment. Ensures one gets created - */ -jasmine.getEnv = function() { - return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isArray_ = function(value) { - return jasmine.isA_("Array", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isString_ = function(value) { - return jasmine.isA_("String", value); -}; - -/** - * @ignore - * @private - * @param value - * @returns {Boolean} - */ -jasmine.isNumber_ = function(value) { - return jasmine.isA_("Number", value); -}; - -/** - * @ignore - * @private - * @param {String} typeName - * @param value - * @returns {Boolean} - */ -jasmine.isA_ = function(typeName, value) { - return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; -}; - -/** - * Pretty printer for expecations. Takes any object and turns it into a human-readable string. - * - * @param value {Object} an object to be outputted - * @returns {String} - */ -jasmine.pp = function(value) { - var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); - stringPrettyPrinter.format(value); - return stringPrettyPrinter.string; -}; - -/** - * Returns true if the object is a DOM Node. - * - * @param {Object} obj object to check - * @returns {Boolean} - */ -jasmine.isDomNode = function(obj) { - return obj['nodeType'] > 0; -}; - -/** - * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. - * - * @example - * // don't care about which function is passed in, as long as it's a function - * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); - * - * @param {Class} clazz - * @returns matchable object of the type clazz - */ -jasmine.any = function(clazz) { - return new jasmine.Matchers.Any(clazz); -}; - -/** - * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. - * - * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine - * expectation syntax. Spies can be checked if they were called or not and what the calling params were. - * - * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). - * - * Spies are torn down at the end of every spec. - * - * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. - * - * @example - * // a stub - * var myStub = jasmine.createSpy('myStub'); // can be used anywhere - * - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // actual foo.not will not be called, execution stops - * spyOn(foo, 'not'); - - // foo.not spied upon, execution will continue to implementation - * spyOn(foo, 'not').andCallThrough(); - * - * // fake example - * var foo = { - * not: function(bool) { return !bool; } - * } - * - * // foo.not(val) will return val - * spyOn(foo, 'not').andCallFake(function(value) {return value;}); - * - * // mock example - * foo.not(7 == 7); - * expect(foo.not).toHaveBeenCalled(); - * expect(foo.not).toHaveBeenCalledWith(true); - * - * @constructor - * @see spyOn, jasmine.createSpy, jasmine.createSpyObj - * @param {String} name - */ -jasmine.Spy = function(name) { - /** - * The name of the spy, if provided. - */ - this.identity = name || 'unknown'; - /** - * Is this Object a spy? - */ - this.isSpy = true; - /** - * The actual function this spy stubs. - */ - this.plan = function() { - }; - /** - * Tracking of the most recent call to the spy. - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy.mostRecentCall.args = [1, 2]; - */ - this.mostRecentCall = {}; - - /** - * Holds arguments for each call to the spy, indexed by call count - * @example - * var mySpy = jasmine.createSpy('foo'); - * mySpy(1, 2); - * mySpy(7, 8); - * mySpy.mostRecentCall.args = [7, 8]; - * mySpy.argsForCall[0] = [1, 2]; - * mySpy.argsForCall[1] = [7, 8]; - */ - this.argsForCall = []; - this.calls = []; -}; - -/** - * Tells a spy to call through to the actual implemenatation. - * - * @example - * var foo = { - * bar: function() { // do some stuff } - * } - * - * // defining a spy on an existing property: foo.bar - * spyOn(foo, 'bar').andCallThrough(); - */ -jasmine.Spy.prototype.andCallThrough = function() { - this.plan = this.originalValue; - return this; -}; - -/** - * For setting the return value of a spy. - * - * @example - * // defining a spy from scratch: foo() returns 'baz' - * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); - * - * // defining a spy on an existing property: foo.bar() returns 'baz' - * spyOn(foo, 'bar').andReturn('baz'); - * - * @param {Object} value - */ -jasmine.Spy.prototype.andReturn = function(value) { - this.plan = function() { - return value; - }; - return this; -}; - -/** - * For throwing an exception when a spy is called. - * - * @example - * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' - * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); - * - * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' - * spyOn(foo, 'bar').andThrow('baz'); - * - * @param {String} exceptionMsg - */ -jasmine.Spy.prototype.andThrow = function(exceptionMsg) { - this.plan = function() { - throw exceptionMsg; - }; - return this; -}; - -/** - * Calls an alternate implementation when a spy is called. - * - * @example - * var baz = function() { - * // do some stuff, return something - * } - * // defining a spy from scratch: foo() calls the function baz - * var foo = jasmine.createSpy('spy on foo').andCall(baz); - * - * // defining a spy on an existing property: foo.bar() calls an anonymnous function - * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); - * - * @param {Function} fakeFunc - */ -jasmine.Spy.prototype.andCallFake = function(fakeFunc) { - this.plan = fakeFunc; - return this; -}; - -/** - * Resets all of a spy's the tracking variables so that it can be used again. - * - * @example - * spyOn(foo, 'bar'); - * - * foo.bar(); - * - * expect(foo.bar.callCount).toEqual(1); - * - * foo.bar.reset(); - * - * expect(foo.bar.callCount).toEqual(0); - */ -jasmine.Spy.prototype.reset = function() { - this.wasCalled = false; - this.callCount = 0; - this.argsForCall = []; - this.calls = []; - this.mostRecentCall = {}; -}; - -jasmine.createSpy = function(name) { - - var spyObj = function() { - spyObj.wasCalled = true; - spyObj.callCount++; - var args = jasmine.util.argsToArray(arguments); - spyObj.mostRecentCall.object = this; - spyObj.mostRecentCall.args = args; - spyObj.argsForCall.push(args); - spyObj.calls.push({object: this, args: args}); - return spyObj.plan.apply(this, arguments); - }; - - var spy = new jasmine.Spy(name); - - for (var prop in spy) { - spyObj[prop] = spy[prop]; - } - - spyObj.reset(); - - return spyObj; -}; - -/** - * Determines whether an object is a spy. - * - * @param {jasmine.Spy|Object} putativeSpy - * @returns {Boolean} - */ -jasmine.isSpy = function(putativeSpy) { - return putativeSpy && putativeSpy.isSpy; -}; - -/** - * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something - * large in one call. - * - * @param {String} baseName name of spy class - * @param {Array} methodNames array of names of methods to make spies - */ -jasmine.createSpyObj = function(baseName, methodNames) { - if (!jasmine.isArray_(methodNames) || methodNames.length == 0) { - throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); - } - var obj = {}; - for (var i = 0; i < methodNames.length; i++) { - obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); - } - return obj; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the current spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.log = function() { - var spec = jasmine.getEnv().currentSpec; - spec.log.apply(spec, arguments); -}; - -/** - * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. - * - * @example - * // spy example - * var foo = { - * not: function(bool) { return !bool; } - * } - * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops - * - * @see jasmine.createSpy - * @param obj - * @param methodName - * @returns a Jasmine spy that can be chained with all spy methods - */ -var spyOn = function(obj, methodName) { - return jasmine.getEnv().currentSpec.spyOn(obj, methodName); -}; - -/** - * Creates a Jasmine spec that will be added to the current suite. - * - * // TODO: pending tests - * - * @example - * it('should be true', function() { - * expect(true).toEqual(true); - * }); - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var it = function(desc, func) { - return jasmine.getEnv().it(desc, func); -}; - -/** - * Creates a disabled Jasmine spec. - * - * A convenience method that allows existing specs to be disabled temporarily during development. - * - * @param {String} desc description of this specification - * @param {Function} func defines the preconditions and expectations of the spec - */ -var xit = function(desc, func) { - return jasmine.getEnv().xit(desc, func); -}; - -/** - * Starts a chain for a Jasmine expectation. - * - * It is passed an Object that is the actual value and should chain to one of the many - * jasmine.Matchers functions. - * - * @param {Object} actual Actual value to test against and expected value - */ -var expect = function(actual) { - return jasmine.getEnv().currentSpec.expect(actual); -}; - -/** - * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. - * - * @param {Function} func Function that defines part of a jasmine spec. - */ -var runs = function(func) { - jasmine.getEnv().currentSpec.runs(func); -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -var waits = function(timeout) { - jasmine.getEnv().currentSpec.waits(timeout); -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); -}; - -/** - * A function that is called before each spec in a suite. - * - * Used for spec setup, including validating assumptions. - * - * @param {Function} beforeEachFunction - */ -var beforeEach = function(beforeEachFunction) { - jasmine.getEnv().beforeEach(beforeEachFunction); -}; - -/** - * A function that is called after each spec in a suite. - * - * Used for restoring any state that is hijacked during spec execution. - * - * @param {Function} afterEachFunction - */ -var afterEach = function(afterEachFunction) { - jasmine.getEnv().afterEach(afterEachFunction); -}; - -/** - * Defines a suite of specifications. - * - * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared - * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization - * of setup in some tests. - * - * @example - * // TODO: a simple suite - * - * // TODO: a simple suite with a nested describe block - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var describe = function(description, specDefinitions) { - return jasmine.getEnv().describe(description, specDefinitions); -}; - -/** - * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. - * - * @param {String} description A string, usually the class under test. - * @param {Function} specDefinitions function that defines several specs. - */ -var xdescribe = function(description, specDefinitions) { - return jasmine.getEnv().xdescribe(description, specDefinitions); -}; - - -// Provide the XMLHttpRequest class for IE 5.x-6.x: -jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { - try { - return new ActiveXObject("Msxml2.XMLHTTP.6.0"); - } catch(e) { - } - try { - return new ActiveXObject("Msxml2.XMLHTTP.3.0"); - } catch(e) { - } - try { - return new ActiveXObject("Msxml2.XMLHTTP"); - } catch(e) { - } - try { - return new ActiveXObject("Microsoft.XMLHTTP"); - } catch(e) { - } - throw new Error("This browser does not support XMLHttpRequest."); -} : XMLHttpRequest; -/** - * @namespace - */ -jasmine.util = {}; - -/** - * Declare that a child class inherit it's prototype from the parent class. - * - * @private - * @param {Function} childClass - * @param {Function} parentClass - */ -jasmine.util.inherit = function(childClass, parentClass) { - /** - * @private - */ - var subclass = function() { - }; - subclass.prototype = parentClass.prototype; - childClass.prototype = new subclass; -}; - -jasmine.util.formatException = function(e) { - var lineNumber; - if (e.line) { - lineNumber = e.line; - } - else if (e.lineNumber) { - lineNumber = e.lineNumber; - } - - var file; - - if (e.sourceURL) { - file = e.sourceURL; - } - else if (e.fileName) { - file = e.fileName; - } - - var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); - - if (file && lineNumber) { - message += ' in ' + file + ' (line ' + lineNumber + ')'; - } - - return message; -}; - -jasmine.util.htmlEscape = function(str) { - if (!str) return str; - return str.replace(/&/g, '&') - .replace(//g, '>'); -}; - -jasmine.util.argsToArray = function(args) { - var arrayOfArgs = []; - for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); - return arrayOfArgs; -}; - -jasmine.util.extend = function(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; -}; - -/** - * Environment for Jasmine - * - * @constructor - */ -jasmine.Env = function() { - this.currentSpec = null; - this.currentSuite = null; - this.currentRunner_ = new jasmine.Runner(this); - - this.reporter = new jasmine.MultiReporter(); - - this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; - this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; - this.lastUpdate = 0; - this.specFilter = function() { - return true; - }; - - this.nextSpecId_ = 0; - this.nextSuiteId_ = 0; - this.equalityTesters_ = []; - - // wrap matchers - this.matchersClass = function() { - jasmine.Matchers.apply(this, arguments); - }; - jasmine.util.inherit(this.matchersClass, jasmine.Matchers); - - jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); -}; - - -jasmine.Env.prototype.setTimeout = jasmine.setTimeout; -jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; -jasmine.Env.prototype.setInterval = jasmine.setInterval; -jasmine.Env.prototype.clearInterval = jasmine.clearInterval; - -/** - * @returns an object containing jasmine version build info, if set. - */ -jasmine.Env.prototype.version = function () { - if (jasmine.version_) { - return jasmine.version_; - } else { - throw new Error('Version not set'); - } -}; - -/** - * @returns string containing jasmine version build info, if set. - */ -jasmine.Env.prototype.versionString = function() { - if (jasmine.version_) { - var version = this.version(); - return version.major + "." + version.minor + "." + version.build + " revision " + version.revision; - } else { - return "version unknown"; - } -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSpecId = function () { - return this.nextSpecId_++; -}; - -/** - * @returns a sequential integer starting at 0 - */ -jasmine.Env.prototype.nextSuiteId = function () { - return this.nextSuiteId_++; -}; - -/** - * Register a reporter to receive status updates from Jasmine. - * @param {jasmine.Reporter} reporter An object which will receive status updates. - */ -jasmine.Env.prototype.addReporter = function(reporter) { - this.reporter.addReporter(reporter); -}; - -jasmine.Env.prototype.execute = function() { - this.currentRunner_.execute(); -}; - -jasmine.Env.prototype.describe = function(description, specDefinitions) { - var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); - - var parentSuite = this.currentSuite; - if (parentSuite) { - parentSuite.add(suite); - } else { - this.currentRunner_.add(suite); - } - - this.currentSuite = suite; - - var declarationError = null; - try { - specDefinitions.call(suite); - } catch(e) { - declarationError = e; - } - - this.currentSuite = parentSuite; - - if (declarationError) { - this.it("encountered a declaration exception", function() { - throw declarationError; - }); - } - - return suite; -}; - -jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { - if (this.currentSuite) { - this.currentSuite.beforeEach(beforeEachFunction); - } else { - this.currentRunner_.beforeEach(beforeEachFunction); - } -}; - -jasmine.Env.prototype.currentRunner = function () { - return this.currentRunner_; -}; - -jasmine.Env.prototype.afterEach = function(afterEachFunction) { - if (this.currentSuite) { - this.currentSuite.afterEach(afterEachFunction); - } else { - this.currentRunner_.afterEach(afterEachFunction); - } - -}; - -jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { - return { - execute: function() { - } - }; -}; - -jasmine.Env.prototype.it = function(description, func) { - var spec = new jasmine.Spec(this, this.currentSuite, description); - this.currentSuite.add(spec); - this.currentSpec = spec; - - if (func) { - spec.runs(func); - } - - return spec; -}; - -jasmine.Env.prototype.xit = function(desc, func) { - return { - id: this.nextSpecId(), - runs: function() { - } - }; -}; - -jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { - if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { - return true; - } - - a.__Jasmine_been_here_before__ = b; - b.__Jasmine_been_here_before__ = a; - - var hasKey = function(obj, keyName) { - return obj != null && obj[keyName] !== jasmine.undefined; - }; - - for (var property in b) { - if (!hasKey(a, property) && hasKey(b, property)) { - mismatchKeys.push("expected has key '" + property + "', but missing from actual."); - } - } - for (property in a) { - if (!hasKey(b, property) && hasKey(a, property)) { - mismatchKeys.push("expected missing key '" + property + "', but present in actual."); - } - } - for (property in b) { - if (property == '__Jasmine_been_here_before__') continue; - if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { - mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); - } - } - - if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { - mismatchValues.push("arrays were not the same length"); - } - - delete a.__Jasmine_been_here_before__; - delete b.__Jasmine_been_here_before__; - return (mismatchKeys.length == 0 && mismatchValues.length == 0); -}; - -jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { - mismatchKeys = mismatchKeys || []; - mismatchValues = mismatchValues || []; - - for (var i = 0; i < this.equalityTesters_.length; i++) { - var equalityTester = this.equalityTesters_[i]; - var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); - if (result !== jasmine.undefined) return result; - } - - if (a === b) return true; - - if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { - return (a == jasmine.undefined && b == jasmine.undefined); - } - - if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { - return a === b; - } - - if (a instanceof Date && b instanceof Date) { - return a.getTime() == b.getTime(); - } - - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); - } - - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); - } - - if (jasmine.isString_(a) && jasmine.isString_(b)) { - return (a == b); - } - - if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { - return (a == b); - } - - if (typeof a === "object" && typeof b === "object") { - return this.compareObjects_(a, b, mismatchKeys, mismatchValues); - } - - //Straight check - return (a === b); -}; - -jasmine.Env.prototype.contains_ = function(haystack, needle) { - if (jasmine.isArray_(haystack)) { - for (var i = 0; i < haystack.length; i++) { - if (this.equals_(haystack[i], needle)) return true; - } - return false; - } - return haystack.indexOf(needle) >= 0; -}; - -jasmine.Env.prototype.addEqualityTester = function(equalityTester) { - this.equalityTesters_.push(equalityTester); -}; -/** No-op base class for Jasmine reporters. - * - * @constructor - */ -jasmine.Reporter = function() { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportRunnerResults = function(runner) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecStarting = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.reportSpecResults = function(spec) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.Reporter.prototype.log = function(str) { -}; - -/** - * Blocks are functions with executable code that make up a spec. - * - * @constructor - * @param {jasmine.Env} env - * @param {Function} func - * @param {jasmine.Spec} spec - */ -jasmine.Block = function(env, func, spec) { - this.env = env; - this.func = func; - this.spec = spec; -}; - -jasmine.Block.prototype.execute = function(onComplete) { - try { - this.func.apply(this.spec); - } catch (e) { - this.spec.fail(e); - } - onComplete(); -}; -/** JavaScript API reporter. - * - * @constructor - */ -jasmine.JsApiReporter = function() { - this.started = false; - this.finished = false; - this.suites_ = []; - this.results_ = {}; -}; - -jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { - this.started = true; - var suites = runner.topLevelSuites(); - for (var i = 0; i < suites.length; i++) { - var suite = suites[i]; - this.suites_.push(this.summarize_(suite)); - } -}; - -jasmine.JsApiReporter.prototype.suites = function() { - return this.suites_; -}; - -jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { - var isSuite = suiteOrSpec instanceof jasmine.Suite; - var summary = { - id: suiteOrSpec.id, - name: suiteOrSpec.description, - type: isSuite ? 'suite' : 'spec', - children: [] - }; - - if (isSuite) { - var children = suiteOrSpec.children(); - for (var i = 0; i < children.length; i++) { - summary.children.push(this.summarize_(children[i])); - } - } - return summary; -}; - -jasmine.JsApiReporter.prototype.results = function() { - return this.results_; -}; - -jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { - return this.results_[specId]; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { - this.finished = true; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { - this.results_[spec.id] = { - messages: spec.results().getItems(), - result: spec.results().failedCount > 0 ? "failed" : "passed" - }; -}; - -//noinspection JSUnusedLocalSymbols -jasmine.JsApiReporter.prototype.log = function(str) { -}; - -jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ - var results = {}; - for (var i = 0; i < specIds.length; i++) { - var specId = specIds[i]; - results[specId] = this.summarizeResult_(this.results_[specId]); - } - return results; -}; - -jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ - var summaryMessages = []; - var messagesLength = result.messages.length; - for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { - var resultMessage = result.messages[messageIndex]; - summaryMessages.push({ - text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, - passed: resultMessage.passed ? resultMessage.passed() : true, - type: resultMessage.type, - message: resultMessage.message, - trace: { - stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined - } - }); - } - - return { - result : result.result, - messages : summaryMessages - }; -}; - -/** - * @constructor - * @param {jasmine.Env} env - * @param actual - * @param {jasmine.Spec} spec - */ -jasmine.Matchers = function(env, actual, spec, opt_isNot) { - this.env = env; - this.actual = actual; - this.spec = spec; - this.isNot = opt_isNot || false; - this.reportWasCalled_ = false; -}; - -// todo: @deprecated as of Jasmine 0.11, remove soon [xw] -jasmine.Matchers.pp = function(str) { - throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); -}; - -// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] -jasmine.Matchers.prototype.report = function(result, failing_message, details) { - throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); -}; - -jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { - for (var methodName in prototype) { - if (methodName == 'report') continue; - var orig = prototype[methodName]; - matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); - } -}; - -jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { - return function() { - var matcherArgs = jasmine.util.argsToArray(arguments); - var result = matcherFunction.apply(this, arguments); - - if (this.isNot) { - result = !result; - } - - if (this.reportWasCalled_) return result; - - var message; - if (!result) { - if (this.message) { - message = this.message.apply(this, arguments); - if (jasmine.isArray_(message)) { - message = message[this.isNot ? 1 : 0]; - } - } else { - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; - if (matcherArgs.length > 0) { - for (var i = 0; i < matcherArgs.length; i++) { - if (i > 0) message += ","; - message += " " + jasmine.pp(matcherArgs[i]); - } - } - message += "."; - } - } - var expectationResult = new jasmine.ExpectationResult({ - matcherName: matcherName, - passed: result, - expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], - actual: this.actual, - message: message - }); - this.spec.addMatcherResult(expectationResult); - return jasmine.undefined; - }; -}; - - - - -/** - * toBe: compares the actual to the expected using === - * @param expected - */ -jasmine.Matchers.prototype.toBe = function(expected) { - return this.actual === expected; -}; - -/** - * toNotBe: compares the actual to the expected using !== - * @param expected - * @deprecated as of 1.0. Use not.toBe() instead. - */ -jasmine.Matchers.prototype.toNotBe = function(expected) { - return this.actual !== expected; -}; - -/** - * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. - * - * @param expected - */ -jasmine.Matchers.prototype.toEqual = function(expected) { - return this.env.equals_(this.actual, expected); -}; - -/** - * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual - * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. - */ -jasmine.Matchers.prototype.toNotEqual = function(expected) { - return !this.env.equals_(this.actual, expected); -}; - -/** - * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes - * a pattern or a String. - * - * @param expected - */ -jasmine.Matchers.prototype.toMatch = function(expected) { - return new RegExp(expected).test(this.actual); -}; - -/** - * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch - * @param expected - * @deprecated as of 1.0. Use not.toMatch() instead. - */ -jasmine.Matchers.prototype.toNotMatch = function(expected) { - return !(new RegExp(expected).test(this.actual)); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeDefined = function() { - return (this.actual !== jasmine.undefined); -}; - -/** - * Matcher that compares the actual to jasmine.undefined. - */ -jasmine.Matchers.prototype.toBeUndefined = function() { - return (this.actual === jasmine.undefined); -}; - -/** - * Matcher that compares the actual to null. - */ -jasmine.Matchers.prototype.toBeNull = function() { - return (this.actual === null); -}; - -/** - * Matcher that boolean not-nots the actual. - */ -jasmine.Matchers.prototype.toBeTruthy = function() { - return !!this.actual; -}; - - -/** - * Matcher that boolean nots the actual. - */ -jasmine.Matchers.prototype.toBeFalsy = function() { - return !this.actual; -}; - - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called. - */ -jasmine.Matchers.prototype.toHaveBeenCalled = function() { - if (arguments.length > 0) { - throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to have been called.", - "Expected spy " + this.actual.identity + " not to have been called." - ]; - }; - - return this.actual.wasCalled; -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ -jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was not called. - * - * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead - */ -jasmine.Matchers.prototype.wasNotCalled = function() { - if (arguments.length > 0) { - throw new Error('wasNotCalled does not take arguments'); - } - - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy " + this.actual.identity + " to not have been called.", - "Expected spy " + this.actual.identity + " to have been called." - ]; - }; - - return !this.actual.wasCalled; -}; - -/** - * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. - * - * @example - * - */ -jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - this.message = function() { - if (this.actual.callCount == 0) { - // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] - return [ - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was." - ]; - } else { - return [ - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) - ]; - } - }; - - return this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; - -/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ -jasmine.Matchers.prototype.wasNotCalledWith = function() { - var expectedArgs = jasmine.util.argsToArray(arguments); - if (!jasmine.isSpy(this.actual)) { - throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); - } - - this.message = function() { - return [ - "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", - "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" - ] - }; - - return !this.env.contains_(this.actual.argsForCall, expectedArgs); -}; - -/** - * Matcher that checks that the expected item is an element in the actual Array. - * - * @param {Object} expected - */ -jasmine.Matchers.prototype.toContain = function(expected) { - return this.env.contains_(this.actual, expected); -}; - -/** - * Matcher that checks that the expected item is NOT an element in the actual Array. - * - * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. - */ -jasmine.Matchers.prototype.toNotContain = function(expected) { - return !this.env.contains_(this.actual, expected); -}; - -jasmine.Matchers.prototype.toBeLessThan = function(expected) { - return this.actual < expected; -}; - -jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { - return this.actual > expected; -}; - -/** - * Matcher that checks that the expected exception was thrown by the actual. - * - * @param {String} expected - */ -jasmine.Matchers.prototype.toThrow = function(expected) { - var result = false; - var exception; - if (typeof this.actual != 'function') { - throw new Error('Actual is not a function'); - } - try { - this.actual(); - } catch (e) { - exception = e; - } - if (exception) { - result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); - } - - var not = this.isNot ? "not " : ""; - - this.message = function() { - if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { - return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' '); - } else { - return "Expected function to throw an exception."; - } - }; - - return result; -}; - -jasmine.Matchers.Any = function(expectedClass) { - this.expectedClass = expectedClass; -}; - -jasmine.Matchers.Any.prototype.matches = function(other) { - if (this.expectedClass == String) { - return typeof other == 'string' || other instanceof String; - } - - if (this.expectedClass == Number) { - return typeof other == 'number' || other instanceof Number; - } - - if (this.expectedClass == Function) { - return typeof other == 'function' || other instanceof Function; - } - - if (this.expectedClass == Object) { - return typeof other == 'object'; - } - - return other instanceof this.expectedClass; -}; - -jasmine.Matchers.Any.prototype.toString = function() { - return ''; -}; - -/** - * @constructor - */ -jasmine.MultiReporter = function() { - this.subReporters_ = []; -}; -jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); - -jasmine.MultiReporter.prototype.addReporter = function(reporter) { - this.subReporters_.push(reporter); -}; - -(function() { - var functionNames = [ - "reportRunnerStarting", - "reportRunnerResults", - "reportSuiteResults", - "reportSpecStarting", - "reportSpecResults", - "log" - ]; - for (var i = 0; i < functionNames.length; i++) { - var functionName = functionNames[i]; - jasmine.MultiReporter.prototype[functionName] = (function(functionName) { - return function() { - for (var j = 0; j < this.subReporters_.length; j++) { - var subReporter = this.subReporters_[j]; - if (subReporter[functionName]) { - subReporter[functionName].apply(subReporter, arguments); - } - } - }; - })(functionName); - } -})(); -/** - * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults - * - * @constructor - */ -jasmine.NestedResults = function() { - /** - * The total count of results - */ - this.totalCount = 0; - /** - * Number of passed results - */ - this.passedCount = 0; - /** - * Number of failed results - */ - this.failedCount = 0; - /** - * Was this suite/spec skipped? - */ - this.skipped = false; - /** - * @ignore - */ - this.items_ = []; -}; - -/** - * Roll up the result counts. - * - * @param result - */ -jasmine.NestedResults.prototype.rollupCounts = function(result) { - this.totalCount += result.totalCount; - this.passedCount += result.passedCount; - this.failedCount += result.failedCount; -}; - -/** - * Adds a log message. - * @param values Array of message parts which will be concatenated later. - */ -jasmine.NestedResults.prototype.log = function(values) { - this.items_.push(new jasmine.MessageResult(values)); -}; - -/** - * Getter for the results: message & results. - */ -jasmine.NestedResults.prototype.getItems = function() { - return this.items_; -}; - -/** - * Adds a result, tracking counts (total, passed, & failed) - * @param {jasmine.ExpectationResult|jasmine.NestedResults} result - */ -jasmine.NestedResults.prototype.addResult = function(result) { - if (result.type != 'log') { - if (result.items_) { - this.rollupCounts(result); - } else { - this.totalCount++; - if (result.passed()) { - this.passedCount++; - } else { - this.failedCount++; - } - } - } - this.items_.push(result); -}; - -/** - * @returns {Boolean} True if everything below passed - */ -jasmine.NestedResults.prototype.passed = function() { - return this.passedCount === this.totalCount; -}; -/** - * Base class for pretty printing for expectation results. - */ -jasmine.PrettyPrinter = function() { - this.ppNestLevel_ = 0; -}; - -/** - * Formats a value in a nice, human-readable string. - * - * @param value - */ -jasmine.PrettyPrinter.prototype.format = function(value) { - if (this.ppNestLevel_ > 40) { - throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); - } - - this.ppNestLevel_++; - try { - if (value === jasmine.undefined) { - this.emitScalar('undefined'); - } else if (value === null) { - this.emitScalar('null'); - } else if (value === jasmine.getGlobal()) { - this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); - } else if (typeof value === 'string') { - this.emitString(value); - } else if (jasmine.isSpy(value)) { - this.emitScalar("spy on " + value.identity); - } else if (value instanceof RegExp) { - this.emitScalar(value.toString()); - } else if (typeof value === 'function') { - this.emitScalar('Function'); - } else if (typeof value.nodeType === 'number') { - this.emitScalar('HTMLNode'); - } else if (value instanceof Date) { - this.emitScalar('Date(' + value + ')'); - } else if (value.__Jasmine_been_here_before__) { - this.emitScalar(''); - } else if (jasmine.isArray_(value) || typeof value == 'object') { - value.__Jasmine_been_here_before__ = true; - if (jasmine.isArray_(value)) { - this.emitArray(value); - } else { - this.emitObject(value); - } - delete value.__Jasmine_been_here_before__; - } else { - this.emitScalar(value.toString()); - } - } finally { - this.ppNestLevel_--; - } -}; - -jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { - for (var property in obj) { - if (property == '__Jasmine_been_here_before__') continue; - fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false); - } -}; - -jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; - -jasmine.StringPrettyPrinter = function() { - jasmine.PrettyPrinter.call(this); - - this.string = ''; -}; -jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); - -jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { - this.append(value); -}; - -jasmine.StringPrettyPrinter.prototype.emitString = function(value) { - this.append("'" + value + "'"); -}; - -jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { - this.append('[ '); - for (var i = 0; i < array.length; i++) { - if (i > 0) { - this.append(', '); - } - this.format(array[i]); - } - this.append(' ]'); -}; - -jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { - var self = this; - this.append('{ '); - var first = true; - - this.iterateObject(obj, function(property, isGetter) { - if (first) { - first = false; - } else { - self.append(', '); - } - - self.append(property); - self.append(' : '); - if (isGetter) { - self.append(''); - } else { - self.format(obj[property]); - } - }); - - this.append(' }'); -}; - -jasmine.StringPrettyPrinter.prototype.append = function(value) { - this.string += value; -}; -jasmine.Queue = function(env) { - this.env = env; - this.blocks = []; - this.running = false; - this.index = 0; - this.offset = 0; - this.abort = false; -}; - -jasmine.Queue.prototype.addBefore = function(block) { - this.blocks.unshift(block); -}; - -jasmine.Queue.prototype.add = function(block) { - this.blocks.push(block); -}; - -jasmine.Queue.prototype.insertNext = function(block) { - this.blocks.splice((this.index + this.offset + 1), 0, block); - this.offset++; -}; - -jasmine.Queue.prototype.start = function(onComplete) { - this.running = true; - this.onComplete = onComplete; - this.next_(); -}; - -jasmine.Queue.prototype.isRunning = function() { - return this.running; -}; - -jasmine.Queue.LOOP_DONT_RECURSE = true; - -jasmine.Queue.prototype.next_ = function() { - var self = this; - var goAgain = true; - - while (goAgain) { - goAgain = false; - - if (self.index < self.blocks.length && !this.abort) { - var calledSynchronously = true; - var completedSynchronously = false; - - var onComplete = function () { - if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { - completedSynchronously = true; - return; - } - - if (self.blocks[self.index].abort) { - self.abort = true; - } - - self.offset = 0; - self.index++; - - var now = new Date().getTime(); - if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { - self.env.lastUpdate = now; - self.env.setTimeout(function() { - self.next_(); - }, 0); - } else { - if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { - goAgain = true; - } else { - self.next_(); - } - } - }; - self.blocks[self.index].execute(onComplete); - - calledSynchronously = false; - if (completedSynchronously) { - onComplete(); - } - - } else { - self.running = false; - if (self.onComplete) { - self.onComplete(); - } - } - } -}; - -jasmine.Queue.prototype.results = function() { - var results = new jasmine.NestedResults(); - for (var i = 0; i < this.blocks.length; i++) { - if (this.blocks[i].results) { - results.addResult(this.blocks[i].results()); - } - } - return results; -}; - - -/** - * Runner - * - * @constructor - * @param {jasmine.Env} env - */ -jasmine.Runner = function(env) { - var self = this; - self.env = env; - self.queue = new jasmine.Queue(env); - self.before_ = []; - self.after_ = []; - self.suites_ = []; -}; - -jasmine.Runner.prototype.execute = function() { - var self = this; - if (self.env.reporter.reportRunnerStarting) { - self.env.reporter.reportRunnerStarting(this); - } - self.queue.start(function () { - self.finishCallback(); - }); -}; - -jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.splice(0,0,beforeEachFunction); -}; - -jasmine.Runner.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.splice(0,0,afterEachFunction); -}; - - -jasmine.Runner.prototype.finishCallback = function() { - this.env.reporter.reportRunnerResults(this); -}; - -jasmine.Runner.prototype.addSuite = function(suite) { - this.suites_.push(suite); -}; - -jasmine.Runner.prototype.add = function(block) { - if (block instanceof jasmine.Suite) { - this.addSuite(block); - } - this.queue.add(block); -}; - -jasmine.Runner.prototype.specs = function () { - var suites = this.suites(); - var specs = []; - for (var i = 0; i < suites.length; i++) { - specs = specs.concat(suites[i].specs()); - } - return specs; -}; - -jasmine.Runner.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Runner.prototype.topLevelSuites = function() { - var topLevelSuites = []; - for (var i = 0; i < this.suites_.length; i++) { - if (!this.suites_[i].parentSuite) { - topLevelSuites.push(this.suites_[i]); - } - } - return topLevelSuites; -}; - -jasmine.Runner.prototype.results = function() { - return this.queue.results(); -}; -/** - * Internal representation of a Jasmine specification, or test. - * - * @constructor - * @param {jasmine.Env} env - * @param {jasmine.Suite} suite - * @param {String} description - */ -jasmine.Spec = function(env, suite, description) { - if (!env) { - throw new Error('jasmine.Env() required'); - } - if (!suite) { - throw new Error('jasmine.Suite() required'); - } - var spec = this; - spec.id = env.nextSpecId ? env.nextSpecId() : null; - spec.env = env; - spec.suite = suite; - spec.description = description; - spec.queue = new jasmine.Queue(env); - - spec.afterCallbacks = []; - spec.spies_ = []; - - spec.results_ = new jasmine.NestedResults(); - spec.results_.description = description; - spec.matchersClass = null; -}; - -jasmine.Spec.prototype.getFullName = function() { - return this.suite.getFullName() + ' ' + this.description + '.'; -}; - - -jasmine.Spec.prototype.results = function() { - return this.results_; -}; - -/** - * All parameters are pretty-printed and concatenated together, then written to the spec's output. - * - * Be careful not to leave calls to jasmine.log in production code. - */ -jasmine.Spec.prototype.log = function() { - return this.results_.log(arguments); -}; - -jasmine.Spec.prototype.runs = function (func) { - var block = new jasmine.Block(this.env, func, this); - this.addToQueue(block); - return this; -}; - -jasmine.Spec.prototype.addToQueue = function (block) { - if (this.queue.isRunning()) { - this.queue.insertNext(block); - } else { - this.queue.add(block); - } -}; - -/** - * @param {jasmine.ExpectationResult} result - */ -jasmine.Spec.prototype.addMatcherResult = function(result) { - this.results_.addResult(result); -}; - -jasmine.Spec.prototype.expect = function(actual) { - var positive = new (this.getMatchersClass_())(this.env, actual, this); - positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); - return positive; -}; - -/** - * Waits a fixed time period before moving to the next block. - * - * @deprecated Use waitsFor() instead - * @param {Number} timeout milliseconds to wait - */ -jasmine.Spec.prototype.waits = function(timeout) { - var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); - this.addToQueue(waitsFunc); - return this; -}; - -/** - * Waits for the latchFunction to return true before proceeding to the next block. - * - * @param {Function} latchFunction - * @param {String} optional_timeoutMessage - * @param {Number} optional_timeout - */ -jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { - var latchFunction_ = null; - var optional_timeoutMessage_ = null; - var optional_timeout_ = null; - - for (var i = 0; i < arguments.length; i++) { - var arg = arguments[i]; - switch (typeof arg) { - case 'function': - latchFunction_ = arg; - break; - case 'string': - optional_timeoutMessage_ = arg; - break; - case 'number': - optional_timeout_ = arg; - break; - } - } - - var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); - this.addToQueue(waitsForFunc); - return this; -}; - -jasmine.Spec.prototype.fail = function (e) { - var expectationResult = new jasmine.ExpectationResult({ - passed: false, - message: e ? jasmine.util.formatException(e) : 'Exception' - }); - this.results_.addResult(expectationResult); -}; - -jasmine.Spec.prototype.getMatchersClass_ = function() { - return this.matchersClass || this.env.matchersClass; -}; - -jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { - var parent = this.getMatchersClass_(); - var newMatchersClass = function() { - parent.apply(this, arguments); - }; - jasmine.util.inherit(newMatchersClass, parent); - jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); - this.matchersClass = newMatchersClass; -}; - -jasmine.Spec.prototype.finishCallback = function() { - this.env.reporter.reportSpecResults(this); -}; - -jasmine.Spec.prototype.finish = function(onComplete) { - this.removeAllSpies(); - this.finishCallback(); - if (onComplete) { - onComplete(); - } -}; - -jasmine.Spec.prototype.after = function(doAfter) { - if (this.queue.isRunning()) { - this.queue.add(new jasmine.Block(this.env, doAfter, this)); - } else { - this.afterCallbacks.unshift(doAfter); - } -}; - -jasmine.Spec.prototype.execute = function(onComplete) { - var spec = this; - if (!spec.env.specFilter(spec)) { - spec.results_.skipped = true; - spec.finish(onComplete); - return; - } - - this.env.reporter.reportSpecStarting(this); - - spec.env.currentSpec = spec; - - spec.addBeforesAndAftersToQueue(); - - spec.queue.start(function () { - spec.finish(onComplete); - }); -}; - -jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { - var runner = this.env.currentRunner(); - var i; - - for (var suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); - } - } - for (i = 0; i < runner.before_.length; i++) { - this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); - } - for (i = 0; i < this.afterCallbacks.length; i++) { - this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); - } - for (suite = this.suite; suite; suite = suite.parentSuite) { - for (i = 0; i < suite.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); - } - } - for (i = 0; i < runner.after_.length; i++) { - this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); - } -}; - -jasmine.Spec.prototype.explodes = function() { - throw 'explodes function should not have been called'; -}; - -jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { - if (obj == jasmine.undefined) { - throw "spyOn could not find an object to spy upon for " + methodName + "()"; - } - - if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { - throw methodName + '() method does not exist'; - } - - if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { - throw new Error(methodName + ' has already been spied upon'); - } - - var spyObj = jasmine.createSpy(methodName); - - this.spies_.push(spyObj); - spyObj.baseObj = obj; - spyObj.methodName = methodName; - spyObj.originalValue = obj[methodName]; - - obj[methodName] = spyObj; - - return spyObj; -}; - -jasmine.Spec.prototype.removeAllSpies = function() { - for (var i = 0; i < this.spies_.length; i++) { - var spy = this.spies_[i]; - spy.baseObj[spy.methodName] = spy.originalValue; - } - this.spies_ = []; -}; - -/** - * Internal representation of a Jasmine suite. - * - * @constructor - * @param {jasmine.Env} env - * @param {String} description - * @param {Function} specDefinitions - * @param {jasmine.Suite} parentSuite - */ -jasmine.Suite = function(env, description, specDefinitions, parentSuite) { - var self = this; - self.id = env.nextSuiteId ? env.nextSuiteId() : null; - self.description = description; - self.queue = new jasmine.Queue(env); - self.parentSuite = parentSuite; - self.env = env; - self.before_ = []; - self.after_ = []; - self.children_ = []; - self.suites_ = []; - self.specs_ = []; -}; - -jasmine.Suite.prototype.getFullName = function() { - var fullName = this.description; - for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { - fullName = parentSuite.description + ' ' + fullName; - } - return fullName; -}; - -jasmine.Suite.prototype.finish = function(onComplete) { - this.env.reporter.reportSuiteResults(this); - this.finished = true; - if (typeof(onComplete) == 'function') { - onComplete(); - } -}; - -jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { - beforeEachFunction.typeName = 'beforeEach'; - this.before_.unshift(beforeEachFunction); -}; - -jasmine.Suite.prototype.afterEach = function(afterEachFunction) { - afterEachFunction.typeName = 'afterEach'; - this.after_.unshift(afterEachFunction); -}; - -jasmine.Suite.prototype.results = function() { - return this.queue.results(); -}; - -jasmine.Suite.prototype.add = function(suiteOrSpec) { - this.children_.push(suiteOrSpec); - if (suiteOrSpec instanceof jasmine.Suite) { - this.suites_.push(suiteOrSpec); - this.env.currentRunner().addSuite(suiteOrSpec); - } else { - this.specs_.push(suiteOrSpec); - } - this.queue.add(suiteOrSpec); -}; - -jasmine.Suite.prototype.specs = function() { - return this.specs_; -}; - -jasmine.Suite.prototype.suites = function() { - return this.suites_; -}; - -jasmine.Suite.prototype.children = function() { - return this.children_; -}; - -jasmine.Suite.prototype.execute = function(onComplete) { - var self = this; - this.queue.start(function () { - self.finish(onComplete); - }); -}; -jasmine.WaitsBlock = function(env, timeout, spec) { - this.timeout = timeout; - jasmine.Block.call(this, env, null, spec); -}; - -jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); - -jasmine.WaitsBlock.prototype.execute = function (onComplete) { - this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); - this.env.setTimeout(function () { - onComplete(); - }, this.timeout); -}; -/** - * A block which waits for some condition to become true, with timeout. - * - * @constructor - * @extends jasmine.Block - * @param {jasmine.Env} env The Jasmine environment. - * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. - * @param {Function} latchFunction A function which returns true when the desired condition has been met. - * @param {String} message The message to display if the desired condition hasn't been met within the given time period. - * @param {jasmine.Spec} spec The Jasmine spec. - */ -jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { - this.timeout = timeout || env.defaultTimeoutInterval; - this.latchFunction = latchFunction; - this.message = message; - this.totalTimeSpentWaitingForLatch = 0; - jasmine.Block.call(this, env, null, spec); -}; -jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); - -jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; - -jasmine.WaitsForBlock.prototype.execute = function(onComplete) { - this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); - var latchFunctionResult; - try { - latchFunctionResult = this.latchFunction.apply(this.spec); - } catch (e) { - this.spec.fail(e); - onComplete(); - return; - } - - if (latchFunctionResult) { - onComplete(); - } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { - var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); - this.spec.fail({ - name: 'timeout', - message: message - }); - - this.abort = true; - onComplete(); - } else { - this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; - var self = this; - this.env.setTimeout(function() { - self.execute(onComplete); - }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); - } -}; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - - -jasmine.version_= { - "major": 1, - "minor": 0, - "build": 1, - "revision": 1286311016 -}; diff --git a/tests/jasmine/spec/mediawiki.jqueryMsg.spec.data.js b/tests/jasmine/spec/mediawiki.jqueryMsg.spec.data.js deleted file mode 100644 index a867f72c..00000000 --- a/tests/jasmine/spec/mediawiki.jqueryMsg.spec.data.js +++ /dev/null @@ -1,488 +0,0 @@ -// This file stores the results from the PHP parser for certain messages and arguments, -// so we can test the equivalent Javascript libraries. -// Last generated with makeLanguageSpec.php at 2011-01-28T02:04:09+00:00 - -mediaWiki.messages.set( { - "en_undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}", - "en_category-subcat-count": "{{PLURAL:$2|This category has only the following subcategory.|This category has the following {{PLURAL:$1|subcategory|$1 subcategories}}, out of $2 total.}}", - "fr_undelete_short": "Restaurer $1 modification{{PLURAL:$1||s}}", - "fr_category-subcat-count": "Cette cat\u00e9gorie comprend {{PLURAL:$2|la sous-cat\u00e9gorie|$2 sous-cat\u00e9gories, dont {{PLURAL:$1|celle|les $1}}}} ci-dessous.", - "ar_undelete_short": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 {{PLURAL:$1|\u062a\u0639\u062f\u064a\u0644 \u0648\u0627\u062d\u062f|\u062a\u0639\u062f\u064a\u0644\u064a\u0646|$1 \u062a\u0639\u062f\u064a\u0644\u0627\u062a|$1 \u062a\u0639\u062f\u064a\u0644|$1 \u062a\u0639\u062f\u064a\u0644\u0627}}", - "ar_category-subcat-count": "{{PLURAL:$2|\u0644\u0627 \u062a\u0635\u0627\u0646\u064a\u0641 \u0641\u0631\u0639\u064a\u0629 \u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641|\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a \u0627\u0644\u062a\u0627\u0644\u064a \u0641\u0642\u0637.|\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 {{PLURAL:$1||\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a|\u0647\u0630\u064a\u0646 \u0627\u0644\u062a\u0635\u0646\u064a\u0641\u064a\u0646 \u0627\u0644\u0641\u0631\u0639\u064a\u064a\u0646|\u0647\u0630\u0647 \u0627\u0644$1 \u062a\u0635\u0627\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a\u0629|\u0647\u0630\u0647 \u0627\u0644$1 \u062a\u0635\u0646\u064a\u0641\u0627 \u0641\u0631\u0639\u064a\u0627|\u0647\u0630\u0647 \u0627\u0644$1 \u062a\u0635\u0646\u064a\u0641 \u0641\u0631\u0639\u064a}}\u060c \u0645\u0646 \u0625\u062c\u0645\u0627\u0644\u064a $2.}}", - "jp_undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}", - "jp_category-subcat-count": "{{PLURAL:$2|This category has only the following subcategory.|This category has the following {{PLURAL:$1|subcategory|$1 subcategories}}, out of $2 total.}}", - "zh_undelete_short": "\u6062\u590d\u88ab\u5220\u9664\u7684$1\u9879\u4fee\u8ba2", - "zh_category-subcat-count": "{{PLURAL:$2|\u672c\u5206\u7c7b\u53ea\u6709\u4e0b\u5217\u4e00\u4e2a\u5b50\u5206\u7c7b\u3002|\u672c\u5206\u7c7b\u5305\u542b\u4e0b\u5217$1\u4e2a\u5b50\u5206\u7c7b\uff0c\u5171\u6709$2\u4e2a\u5b50\u5206\u7c7b\u3002}}" -} ); -var jasmineMsgSpec = [ - { - "name": "en undelete_short 0", - "key": "en_undelete_short", - "args": [ - 0 - ], - "result": "Undelete 0 edits", - "lang": "en" - }, - { - "name": "en undelete_short 1", - "key": "en_undelete_short", - "args": [ - 1 - ], - "result": "Undelete one edit", - "lang": "en" - }, - { - "name": "en undelete_short 2", - "key": "en_undelete_short", - "args": [ - 2 - ], - "result": "Undelete 2 edits", - "lang": "en" - }, - { - "name": "en undelete_short 5", - "key": "en_undelete_short", - "args": [ - 5 - ], - "result": "Undelete 5 edits", - "lang": "en" - }, - { - "name": "en undelete_short 21", - "key": "en_undelete_short", - "args": [ - 21 - ], - "result": "Undelete 21 edits", - "lang": "en" - }, - { - "name": "en undelete_short 101", - "key": "en_undelete_short", - "args": [ - 101 - ], - "result": "Undelete 101 edits", - "lang": "en" - }, - { - "name": "en category-subcat-count 0,10", - "key": "en_category-subcat-count", - "args": [ - 0, - 10 - ], - "result": "This category has the following 0 subcategories, out of 10 total.", - "lang": "en" - }, - { - "name": "en category-subcat-count 1,1", - "key": "en_category-subcat-count", - "args": [ - 1, - 1 - ], - "result": "This category has only the following subcategory.", - "lang": "en" - }, - { - "name": "en category-subcat-count 1,2", - "key": "en_category-subcat-count", - "args": [ - 1, - 2 - ], - "result": "This category has the following subcategory, out of 2 total.", - "lang": "en" - }, - { - "name": "en category-subcat-count 3,30", - "key": "en_category-subcat-count", - "args": [ - 3, - 30 - ], - "result": "This category has the following 3 subcategories, out of 30 total.", - "lang": "en" - }, - { - "name": "fr undelete_short 0", - "key": "fr_undelete_short", - "args": [ - 0 - ], - "result": "Restaurer 0 modification", - "lang": "fr" - }, - { - "name": "fr undelete_short 1", - "key": "fr_undelete_short", - "args": [ - 1 - ], - "result": "Restaurer 1 modification", - "lang": "fr" - }, - { - "name": "fr undelete_short 2", - "key": "fr_undelete_short", - "args": [ - 2 - ], - "result": "Restaurer 2 modifications", - "lang": "fr" - }, - { - "name": "fr undelete_short 5", - "key": "fr_undelete_short", - "args": [ - 5 - ], - "result": "Restaurer 5 modifications", - "lang": "fr" - }, - { - "name": "fr undelete_short 21", - "key": "fr_undelete_short", - "args": [ - 21 - ], - "result": "Restaurer 21 modifications", - "lang": "fr" - }, - { - "name": "fr undelete_short 101", - "key": "fr_undelete_short", - "args": [ - 101 - ], - "result": "Restaurer 101 modifications", - "lang": "fr" - }, - { - "name": "fr category-subcat-count 0,10", - "key": "fr_category-subcat-count", - "args": [ - 0, - 10 - ], - "result": "Cette cat\u00e9gorie comprend 10 sous-cat\u00e9gories, dont celle ci-dessous.", - "lang": "fr" - }, - { - "name": "fr category-subcat-count 1,1", - "key": "fr_category-subcat-count", - "args": [ - 1, - 1 - ], - "result": "Cette cat\u00e9gorie comprend la sous-cat\u00e9gorie ci-dessous.", - "lang": "fr" - }, - { - "name": "fr category-subcat-count 1,2", - "key": "fr_category-subcat-count", - "args": [ - 1, - 2 - ], - "result": "Cette cat\u00e9gorie comprend 2 sous-cat\u00e9gories, dont celle ci-dessous.", - "lang": "fr" - }, - { - "name": "fr category-subcat-count 3,30", - "key": "fr_category-subcat-count", - "args": [ - 3, - 30 - ], - "result": "Cette cat\u00e9gorie comprend 30 sous-cat\u00e9gories, dont les 3 ci-dessous.", - "lang": "fr" - }, - { - "name": "ar undelete_short 0", - "key": "ar_undelete_short", - "args": [ - 0 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 \u062a\u0639\u062f\u064a\u0644 \u0648\u0627\u062d\u062f", - "lang": "ar" - }, - { - "name": "ar undelete_short 1", - "key": "ar_undelete_short", - "args": [ - 1 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 \u062a\u0639\u062f\u064a\u0644\u064a\u0646", - "lang": "ar" - }, - { - "name": "ar undelete_short 2", - "key": "ar_undelete_short", - "args": [ - 2 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 2 \u062a\u0639\u062f\u064a\u0644\u0627\u062a", - "lang": "ar" - }, - { - "name": "ar undelete_short 5", - "key": "ar_undelete_short", - "args": [ - 5 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 5 \u062a\u0639\u062f\u064a\u0644", - "lang": "ar" - }, - { - "name": "ar undelete_short 21", - "key": "ar_undelete_short", - "args": [ - 21 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 21 \u062a\u0639\u062f\u064a\u0644\u0627", - "lang": "ar" - }, - { - "name": "ar undelete_short 101", - "key": "ar_undelete_short", - "args": [ - 101 - ], - "result": "\u0627\u0633\u062a\u0631\u062c\u0627\u0639 101 \u062a\u0639\u062f\u064a\u0644\u0627", - "lang": "ar" - }, - { - "name": "ar category-subcat-count 0,10", - "key": "ar_category-subcat-count", - "args": [ - 0, - 10 - ], - "result": "\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 \u060c \u0645\u0646 \u0625\u062c\u0645\u0627\u0644\u064a 10.", - "lang": "ar" - }, - { - "name": "ar category-subcat-count 1,1", - "key": "ar_category-subcat-count", - "args": [ - 1, - 1 - ], - "result": "\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a \u0627\u0644\u062a\u0627\u0644\u064a \u0641\u0642\u0637.", - "lang": "ar" - }, - { - "name": "ar category-subcat-count 1,2", - "key": "ar_category-subcat-count", - "args": [ - 1, - 2 - ], - "result": "\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 \u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a\u060c \u0645\u0646 \u0625\u062c\u0645\u0627\u0644\u064a 2.", - "lang": "ar" - }, - { - "name": "ar category-subcat-count 3,30", - "key": "ar_category-subcat-count", - "args": [ - 3, - 30 - ], - "result": "\u0647\u0630\u0627 \u0627\u0644\u062a\u0635\u0646\u064a\u0641 \u0641\u064a\u0647 \u0647\u0630\u0647 \u0627\u06443 \u062a\u0635\u0627\u0646\u064a\u0641 \u0627\u0644\u0641\u0631\u0639\u064a\u0629\u060c \u0645\u0646 \u0625\u062c\u0645\u0627\u0644\u064a 30.", - "lang": "ar" - }, - { - "name": "jp undelete_short 0", - "key": "jp_undelete_short", - "args": [ - 0 - ], - "result": "Undelete 0 edits", - "lang": "jp" - }, - { - "name": "jp undelete_short 1", - "key": "jp_undelete_short", - "args": [ - 1 - ], - "result": "Undelete one edit", - "lang": "jp" - }, - { - "name": "jp undelete_short 2", - "key": "jp_undelete_short", - "args": [ - 2 - ], - "result": "Undelete 2 edits", - "lang": "jp" - }, - { - "name": "jp undelete_short 5", - "key": "jp_undelete_short", - "args": [ - 5 - ], - "result": "Undelete 5 edits", - "lang": "jp" - }, - { - "name": "jp undelete_short 21", - "key": "jp_undelete_short", - "args": [ - 21 - ], - "result": "Undelete 21 edits", - "lang": "jp" - }, - { - "name": "jp undelete_short 101", - "key": "jp_undelete_short", - "args": [ - 101 - ], - "result": "Undelete 101 edits", - "lang": "jp" - }, - { - "name": "jp category-subcat-count 0,10", - "key": "jp_category-subcat-count", - "args": [ - 0, - 10 - ], - "result": "This category has the following 0 subcategories, out of 10 total.", - "lang": "jp" - }, - { - "name": "jp category-subcat-count 1,1", - "key": "jp_category-subcat-count", - "args": [ - 1, - 1 - ], - "result": "This category has only the following subcategory.", - "lang": "jp" - }, - { - "name": "jp category-subcat-count 1,2", - "key": "jp_category-subcat-count", - "args": [ - 1, - 2 - ], - "result": "This category has the following subcategory, out of 2 total.", - "lang": "jp" - }, - { - "name": "jp category-subcat-count 3,30", - "key": "jp_category-subcat-count", - "args": [ - 3, - 30 - ], - "result": "This category has the following 3 subcategories, out of 30 total.", - "lang": "jp" - }, - { - "name": "zh undelete_short 0", - "key": "zh_undelete_short", - "args": [ - 0 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u76840\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh undelete_short 1", - "key": "zh_undelete_short", - "args": [ - 1 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u76841\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh undelete_short 2", - "key": "zh_undelete_short", - "args": [ - 2 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u76842\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh undelete_short 5", - "key": "zh_undelete_short", - "args": [ - 5 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u76845\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh undelete_short 21", - "key": "zh_undelete_short", - "args": [ - 21 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u768421\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh undelete_short 101", - "key": "zh_undelete_short", - "args": [ - 101 - ], - "result": "\u6062\u590d\u88ab\u5220\u9664\u7684101\u9879\u4fee\u8ba2", - "lang": "zh" - }, - { - "name": "zh category-subcat-count 0,10", - "key": "zh_category-subcat-count", - "args": [ - 0, - 10 - ], - "result": "\u672c\u5206\u7c7b\u5305\u542b\u4e0b\u52170\u4e2a\u5b50\u5206\u7c7b\uff0c\u5171\u670910\u4e2a\u5b50\u5206\u7c7b\u3002", - "lang": "zh" - }, - { - "name": "zh category-subcat-count 1,1", - "key": "zh_category-subcat-count", - "args": [ - 1, - 1 - ], - "result": "\u672c\u5206\u7c7b\u53ea\u6709\u4e0b\u5217\u4e00\u4e2a\u5b50\u5206\u7c7b\u3002", - "lang": "zh" - }, - { - "name": "zh category-subcat-count 1,2", - "key": "zh_category-subcat-count", - "args": [ - 1, - 2 - ], - "result": "\u672c\u5206\u7c7b\u5305\u542b\u4e0b\u52171\u4e2a\u5b50\u5206\u7c7b\uff0c\u5171\u67092\u4e2a\u5b50\u5206\u7c7b\u3002", - "lang": "zh" - }, - { - "name": "zh category-subcat-count 3,30", - "key": "zh_category-subcat-count", - "args": [ - 3, - 30 - ], - "result": "\u672c\u5206\u7c7b\u5305\u542b\u4e0b\u52173\u4e2a\u5b50\u5206\u7c7b\uff0c\u5171\u670930\u4e2a\u5b50\u5206\u7c7b\u3002", - "lang": "zh" - } -]; diff --git a/tests/jasmine/spec/mediawiki.jqueryMsg.spec.js b/tests/jasmine/spec/mediawiki.jqueryMsg.spec.js deleted file mode 100644 index 46dcaa80..00000000 --- a/tests/jasmine/spec/mediawiki.jqueryMsg.spec.js +++ /dev/null @@ -1,389 +0,0 @@ -/* spec for language & message behaviour in MediaWiki */ - -mw.messages.set( { - "en_empty": "", - "en_simple": "Simple message", - "en_replace": "Simple $1 replacement", - "en_replace2": "Simple $1 $2 replacements", - "en_link": "Simple [http://example.com link to example].", - "en_link_replace": "Complex [$1 $2] behaviour.", - "en_simple_magic": "Simple {{ALOHOMORA}} message", - "en_undelete_short": "Undelete {{PLURAL:$1|one edit|$1 edits}}", - "en_undelete_empty_param": "Undelete{{PLURAL:$1|| multiple edits}}", - "en_category-subcat-count": "{{PLURAL:$2|This category has only the following subcategory.|This category has the following {{PLURAL:$1|subcategory|$1 subcategories}}, out of $2 total.}}", - "en_escape0": "Escape \\to fantasy island", - "en_escape1": "I had \\$2.50 in my pocket", - "en_escape2": "I had {{PLURAL:$1|the absolute \\|$1\\| which came out to \\$3.00 in my C:\\\\drive| some stuff}}", - "en_fail": "This should fail to {{parse", - "en_fail_magic": "There is no such magic word as {{SIETNAME}}", - "en_evil": "This has tags" -} ); - -/** - * Tests - */ -( function( mw, $, undefined ) { - - describe( "mediaWiki.jqueryMsg", function() { - - describe( "basic message functionality", function() { - - it( "should return identity for empty string", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_empty' ).html() ).toEqual( '' ); - } ); - - - it( "should return identity for simple string", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_simple' ).html() ).toEqual( 'Simple message' ); - } ); - - } ); - - describe( "escaping", function() { - - it ( "should handle simple escaping", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_escape0' ).html() ).toEqual( 'Escape to fantasy island' ); - } ); - - it ( "should escape dollar signs found in ordinary text when backslashed", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_escape1' ).html() ).toEqual( 'I had $2.50 in my pocket' ); - } ); - - it ( "should handle a complicated escaping case, including escaped pipe chars in template args", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_escape2', [ 1 ] ).html() ).toEqual( 'I had the absolute |1| which came out to $3.00 in my C:\\drive' ); - } ); - - } ); - - describe( "replacing", function() { - - it ( "should handle simple replacing", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_replace', [ 'foo' ] ).html() ).toEqual( 'Simple foo replacement' ); - } ); - - it ( "should return $n if replacement not there", function() { - var parser = new mw.jqueryMsg.parser(); - expect( parser.parse( 'en_replace', [] ).html() ).toEqual( 'Simple $1 replacement' ); - expect( parser.parse( 'en_replace2', [ 'bar' ] ).html() ).toEqual( 'Simple bar $2 replacements' ); - } ); - - } ); - - describe( "linking", function() { - - it ( "should handle a simple link", function() { - var parser = new mw.jqueryMsg.parser(); - var parsed = parser.parse( 'en_link' ); - var contents = parsed.contents(); - expect( contents.length ).toEqual( 3 ); - expect( contents[0].nodeName ).toEqual( '#text' ); - expect( contents[0].nodeValue ).toEqual( 'Simple ' ); - expect( contents[1].nodeName ).toEqual( 'A' ); - expect( contents[1].getAttribute( 'href' ) ).toEqual( 'http://example.com' ); - expect( contents[1].childNodes[0].nodeValue ).toEqual( 'link to example' ); - expect( contents[2].nodeName ).toEqual( '#text' ); - expect( contents[2].nodeValue ).toEqual( '.' ); - } ); - - it ( "should replace a URL into a link", function() { - var parser = new mw.jqueryMsg.parser(); - var parsed = parser.parse( 'en_link_replace', [ 'http://example.com/foo', 'linking' ] ); - var contents = parsed.contents(); - expect( contents.length ).toEqual( 3 ); - expect( contents[0].nodeName ).toEqual( '#text' ); - expect( contents[0].nodeValue ).toEqual( 'Complex ' ); - expect( contents[1].nodeName ).toEqual( 'A' ); - expect( contents[1].getAttribute( 'href' ) ).toEqual( 'http://example.com/foo' ); - expect( contents[1].childNodes[0].nodeValue ).toEqual( 'linking' ); - expect( contents[2].nodeName ).toEqual( '#text' ); - expect( contents[2].nodeValue ).toEqual( ' behaviour.' ); - } ); - - it ( "should bind a click handler into a link", function() { - var parser = new mw.jqueryMsg.parser(); - var clicked = false; - var click = function() { clicked = true; }; - var parsed = parser.parse( 'en_link_replace', [ click, 'linking' ] ); - var contents = parsed.contents(); - expect( contents.length ).toEqual( 3 ); - expect( contents[0].nodeName ).toEqual( '#text' ); - expect( contents[0].nodeValue ).toEqual( 'Complex ' ); - expect( contents[1].nodeName ).toEqual( 'A' ); - expect( contents[1].getAttribute( 'href' ) ).toEqual( '#' ); - expect( contents[1].childNodes[0].nodeValue ).toEqual( 'linking' ); - expect( contents[2].nodeName ).toEqual( '#text' ); - expect( contents[2].nodeValue ).toEqual( ' behaviour.' ); - // determining bindings is hard in IE - var anchor = parsed.find( 'a' ); - if ( ( $.browser.mozilla || $.browser.webkit ) && anchor.click ) { - expect( clicked ).toEqual( false ); - anchor.click(); - expect( clicked ).toEqual( true ); - } - } ); - - it ( "should wrap a jquery arg around link contents -- even another element", function() { - var parser = new mw.jqueryMsg.parser(); - var clicked = false; - var click = function() { clicked = true; }; - var button = $( ' behaviour.' ).html(); - var createdHtml = $div.find( '.foo' ).html(); - // it is hard to test for clicks with IE; also it inserts or removes spaces around nodes when creating HTML tags, depending on their type. - // so need to check the strings stripped of spaces. - if ( ( $.browser.mozilla || $.browser.webkit ) && $button.click ) { - expect( createdHtml ).toEqual( expectedHtml ); - $div.find( 'button ').click(); - expect( clicked ).toEqual( true ); - } else if ( $.browser.ie ) { - expect( createdHtml.replace( /\s/, '' ) ).toEqual( expectedHtml.replace( /\s/, '' ) ); - } - delete $.fn.msg; - } ); - - it( "jQuery plugin should escape incoming string arguments", function() { - $.fn.msg = mw.jqueryMsg.getPlugin(); - var $div = $( '
' ).addClass( 'foo' ); - $div.msg( 'en_replace', '

x

' ); // looks like HTML, but as a string, should be escaped. - // passing this through jQuery and back to string, because browsers may have subtle differences, like the case of tag names. - var expectedHtml = $( '
Simple <p>x</p> replacement
' ).html(); - var createdHtml = $div.html(); - expect( expectedHtml ).toEqual( createdHtml ); - delete $.fn.msg; - } ); - - - it( "jQuery plugin should never execute scripts", function() { - window.en_evil = false; - $.fn.msg = mw.jqueryMsg.getPlugin(); - var $div = $( '
' ); - $div.msg( 'en_evil' ); - expect( window.en_evil ).toEqual( false ); - delete $.fn.msg; - } ); - - - // n.b. this passes because jQuery already seems to strip scripts away; however, it still executes them if they are appended to any element. - it( "jQuery plugin should never emit scripts", function() { - $.fn.msg = mw.jqueryMsg.getPlugin(); - var $div = $( '
' ); - $div.msg( 'en_evil' ); - // passing this through jQuery and back to string, because browsers may have subtle differences, like the case of tag names. - var expectedHtml = $( '
This has tags
' ).html(); - var createdHtml = $div.html(); - expect( expectedHtml ).toEqual( createdHtml ); - console.log( 'expected: ' + expectedHtml ); - console.log( 'created: ' + createdHtml ); - delete $.fn.msg; - } ); - - - - } ); - - // The parser functions can throw errors, but let's not actually blow up for the user -- instead dump the error into the interface so we have - // a chance at fixing this - describe( "easy message interface functions with graceful failures", function() { - it( "should allow a global that returns strings, with graceful failure", function() { - var gM = mw.jqueryMsg.getMessageFunction(); - // passing this through jQuery and back to string, because browsers may have subtle differences, like the case of tag names. - // a surrounding is needed for html() to work right - var expectedHtml = $( 'en_fail: Parse error at position 20 in input: This should fail to {{parse' ).html(); - var result = gM( 'en_fail' ); - expect( typeof result ).toEqual( 'string' ); - expect( result ).toEqual( expectedHtml ); - } ); - - it( "should allow a global that returns strings, with graceful failure on missing magic words", function() { - var gM = mw.jqueryMsg.getMessageFunction(); - // passing this through jQuery and back to string, because browsers may have subtle differences, like the case of tag names. - // a surrounding is needed for html() to work right - var expectedHtml = $( 'en_fail_magic: unknown operation "sietname"' ).html(); - var result = gM( 'en_fail_magic' ); - expect( typeof result ).toEqual( 'string' ); - expect( result ).toEqual( expectedHtml ); - } ); - - - it( "should allow a jQuery plugin, with graceful failure", function() { - $.fn.msg = mw.jqueryMsg.getPlugin(); - var $div = $( '
' ).append( $( '

' ).addClass( 'foo' ) ); - $div.find( '.foo' ).msg( 'en_fail' ); - // passing this through jQuery and back to string, because browsers may have subtle differences, like the case of tag names. - // a surrounding is needed for html() to work right - var expectedHtml = $( 'en_fail: Parse error at position 20 in input: This should fail to {{parse' ).html(); - var createdHtml = $div.find( '.foo' ).html(); - expect( createdHtml ).toEqual( expectedHtml ); - delete $.fn.msg; - } ); - - } ); - - - - - describe( "test plurals and other language-specific functions", function() { - /* copying some language definitions in here -- it's hard to make this test fast and reliable - otherwise, and we don't want to have to know the mediawiki URL from this kind of test either. - We also can't preload the langs for the test since they clobber the same namespace. - In principle Roan said it was okay to change how languages worked so that didn't happen... maybe - someday. We'd have to the same kind of importing of the default rules for most rules, or maybe - come up with some kind of subclassing scheme for languages */ - var languageClasses = { - ar: { - /** - * Arabic (العربية) language functions - */ - - convertPlural: function( count, forms ) { - forms = mw.language.preConvertPlural( forms, 6 ); - if ( count === 0 ) { - return forms[0]; - } - if ( count == 1 ) { - return forms[1]; - } - if ( count == 2 ) { - return forms[2]; - } - if ( count % 100 >= 3 && count % 100 <= 10 ) { - return forms[3]; - } - if ( count % 100 >= 11 && count % 100 <= 99 ) { - return forms[4]; - } - return forms[5]; - }, - - digitTransformTable: { - '0': '٠', // ٠ - '1': '١', // ١ - '2': '٢', // ٢ - '3': '٣', // ٣ - '4': '٤', // ٤ - '5': '٥', // ٥ - '6': '٦', // ٦ - '7': '٧', // ٧ - '8': '٨', // ٨ - '9': '٩', // ٩ - '.': '٫', // ٫ wrong table ? - ',': '٬' // ٬ - } - - }, - en: { }, - fr: { - convertPlural: function( count, forms ) { - forms = mw.language.preConvertPlural( forms, 2 ); - return ( count <= 1 ) ? forms[0] : forms[1]; - } - }, - jp: { }, - zh: { } - }; - - /* simulate how the language classes override, or don't, the standard functions in mw.language */ - $.each( languageClasses, function( langCode, rules ) { - $.each( [ 'convertPlural', 'convertNumber' ], function( i, propertyName ) { - if ( typeof rules[ propertyName ] === 'undefined' ) { - rules[ propertyName ] = mw.language[ propertyName ]; - } - } ); - } ); - - $.each( jasmineMsgSpec, function( i, test ) { - it( "should parse " + test.name, function() { - // using language override so we don't have to muck with global namespace - var parser = new mw.jqueryMsg.parser( { language: languageClasses[ test.lang ] } ); - var parsedHtml = parser.parse( test.key, test.args ).html(); - expect( parsedHtml ).toEqual( test.result ); - } ); - } ); - - } ); - - } ); -} )( window.mediaWiki, jQuery ); diff --git a/tests/jasmine/spec_makers/makeJqueryMsgSpec.php b/tests/jasmine/spec_makers/makeJqueryMsgSpec.php deleted file mode 100644 index 840da96a..00000000 --- a/tests/jasmine/spec_makers/makeJqueryMsgSpec.php +++ /dev/null @@ -1,110 +0,0 @@ - array( - array( 0 ), - array( 1 ), - array( 2 ), - array( 5 ), - array( 21 ), - array( 101 ) - ), - 'category-subcat-count' => array( - array( 0, 10 ), - array( 1, 1 ), - array( 1, 2 ), - array( 3, 30 ) - ) - ); - - public function __construct() { - parent::__construct(); - $this->mDescription = "Create a JasmineBDD-compatible specification for message parsing"; - // add any other options here - } - - public function execute() { - list( $messages, $tests ) = $this->getMessagesAndTests(); - $this->writeJavascriptFile( $messages, $tests, "spec/mediawiki.language.parser.spec.data.js" ); - } - - private function getMessagesAndTests() { - $messages = array(); - $tests = array(); - foreach ( array( 'en', 'fr', 'ar', 'jp', 'zh' ) as $languageCode ) { - foreach ( self::$keyToTestArgs as $key => $testArgs ) { - foreach ($testArgs as $args) { - // get the raw template, without any transformations - $template = wfMessage( $key )->inLanguage( $languageCode )->plain(); - - $result = wfMessage( $key, $args )->inLanguage( $languageCode )->text(); - - // record the template, args, language, and expected result - // fake multiple languages by flattening them together - $langKey = $languageCode . '_' . $key; - $messages[ $langKey ] = $template; - $tests[] = array( - 'name' => $languageCode . " " . $key . " " . join( ",", $args ), - 'key' => $langKey, - 'args' => $args, - 'result' => $result, - 'lang' => $languageCode - ); - } - } - } - return array( $messages, $tests ); - } - - private function writeJavascriptFile( $messages, $tests, $dataSpecFile ) { - global $argv; - $arguments = count($argv) ? $argv : $_SERVER[ 'argv' ]; - - $json = new Services_JSON; - $json->pretty = true; - $javascriptPrologue = "// This file stores the results from the PHP parser for certain messages and arguments,\n" - . "// so we can test the equivalent Javascript libraries.\n" - . '// Last generated with ' . join(' ', $arguments) . ' at ' . gmdate('c') . "\n\n"; - $javascriptMessages = "mediaWiki.messages.set( " . $json->encode( $messages, true ) . " );\n"; - $javascriptTests = 'var jasmineMsgSpec = ' . $json->encode( $tests, true ) . ";\n"; - - $fp = fopen( $dataSpecFile, 'w' ); - if ( !$fp ) { - die( "couldn't open $dataSpecFile for writing" ); - } - $success = fwrite( $fp, $javascriptPrologue . $javascriptMessages . $javascriptTests ); - if ( !$success ) { - die( "couldn't write to $dataSpecFile" ); - } - $success = fclose( $fp ); - if ( !$success ) { - die( "couldn't close $dataSpecFile" ); - } - } -} - -$maintClass = "MakeLanguageSpec"; -require_once( "$maintenanceDir/doMaintenance.php" ); - - - diff --git a/tests/parser/README b/tests/parser/README deleted file mode 100644 index 8b413376..00000000 --- a/tests/parser/README +++ /dev/null @@ -1,8 +0,0 @@ -Parser tests are run using our PHPUnit test suite in tests/phpunit: - - $ cd tests/phpunit - ./phpunit.php --group Parser - -You can optionally filter by title using --regex. I.e. : - - ./phpunit.php --group Parser --regex="Bug 6200" diff --git a/tests/parser/extraParserTests.txt b/tests/parser/extraParserTests.txt deleted file mode 100644 index bef8f506..00000000 Binary files a/tests/parser/extraParserTests.txt and /dev/null differ diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc deleted file mode 100644 index 86e1e192..00000000 --- a/tests/parser/parserTest.inc +++ /dev/null @@ -1,1330 +0,0 @@ - -# http://www.mediawiki.org/ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# http://www.gnu.org/copyleft/gpl.html - -/** - * @todo Make this more independent of the configuration (and if possible the database) - * @todo document - * @file - * @ingroup Testing - */ - -/** - * @ingroup Testing - */ -class ParserTest { - /** - * boolean $color whereas output should be colorized - */ - private $color; - - /** - * boolean $showOutput Show test output - */ - private $showOutput; - - /** - * boolean $useTemporaryTables Use temporary tables for the temporary database - */ - private $useTemporaryTables = true; - - /** - * boolean $databaseSetupDone True if the database has been set up - */ - private $databaseSetupDone = false; - - /** - * Our connection to the database - * @var DatabaseBase - */ - private $db; - - /** - * Database clone helper - * @var CloneDatabase - */ - private $dbClone; - - /** - * string $oldTablePrefix Original table prefix - */ - private $oldTablePrefix; - - private $maxFuzzTestLength = 300; - private $fuzzSeed = 0; - private $memoryLimit = 50; - private $uploadDir = null; - - public $regex = ""; - private $savedGlobals = array(); - /** - * Sets terminal colorization and diff/quick modes depending on OS and - * command-line options (--color and --quick). - */ - public function __construct( $options = array() ) { - # Only colorize output if stdout is a terminal. - $this->color = !wfIsWindows() && Maintenance::posix_isatty( 1 ); - - if ( isset( $options['color'] ) ) { - switch( $options['color'] ) { - case 'no': - $this->color = false; - break; - case 'yes': - default: - $this->color = true; - break; - } - } - - $this->term = $this->color - ? new AnsiTermColorer() - : new DummyTermColorer(); - - $this->showDiffs = !isset( $options['quick'] ); - $this->showProgress = !isset( $options['quiet'] ); - $this->showFailure = !( - isset( $options['quiet'] ) - && ( isset( $options['record'] ) - || isset( $options['compare'] ) ) ); // redundant output - - $this->showOutput = isset( $options['show-output'] ); - - if ( isset( $options['filter'] ) ) { - $options['regex'] = $options['filter']; - } - - if ( isset( $options['regex'] ) ) { - if ( isset( $options['record'] ) ) { - echo "Warning: --record cannot be used with --regex, disabling --record\n"; - unset( $options['record'] ); - } - $this->regex = $options['regex']; - } else { - # Matches anything - $this->regex = ''; - } - - $this->setupRecorder( $options ); - $this->keepUploads = isset( $options['keep-uploads'] ); - - if ( isset( $options['seed'] ) ) { - $this->fuzzSeed = intval( $options['seed'] ) - 1; - } - - $this->runDisabled = isset( $options['run-disabled'] ); - - $this->hooks = array(); - $this->functionHooks = array(); - self::setUp(); - } - - static function setUp() { - global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, - $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, - $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, - $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, - $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers; - - $wgScript = '/index.php'; - $wgScriptPath = '/'; - $wgArticlePath = '/wiki/$1'; - $wgStyleSheetPath = '/skins'; - $wgStylePath = '/skins'; - $wgExtensionAssetsPath = '/extensions'; - $wgThumbnailScriptPath = false; - $wgLockManagers = array( array( - 'name' => 'fsLockManager', - 'class' => 'FSLockManager', - 'lockDirectory' => wfTempDir() . '/test-repo/lockdir', - ) ); - $wgLocalFileRepo = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'local-public' => wfTempDir() . '/test-repo/public', - 'local-thumb' => wfTempDir() . '/test-repo/thumb', - 'local-temp' => wfTempDir() . '/test-repo/temp', - 'local-deleted' => wfTempDir() . '/test-repo/deleted', - ) - ) ) - ); - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - // XXX: tests won't run without this (for CACHE_DB) - if ( $wgMainCacheType === CACHE_DB ) { - $wgMainCacheType = CACHE_NONE; - } - if ( $wgMessageCacheType === CACHE_DB ) { - $wgMessageCacheType = CACHE_NONE; - } - if ( $wgParserCacheType === CACHE_DB ) { - $wgParserCacheType = CACHE_NONE; - } - - $wgEnableParserCache = false; - DeferredUpdates::clearPendingUpdates(); - $wgMemc = wfGetMainCache(); // checks $wgMainCacheType - $messageMemc = wfGetMessageCacheStorage(); - $parserMemc = wfGetParserCacheStorage(); - - // $wgContLang = new StubContLang; - $wgUser = new User; - $context = new RequestContext; - $wgLang = $context->getLanguage(); - $wgOut = $context->getOutput(); - $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); - $wgRequest = $context->getRequest(); - - if ( $wgStyleDirectory === false ) { - $wgStyleDirectory = "$IP/skins"; - } - - } - - public function setupRecorder ( $options ) { - if ( isset( $options['record'] ) ) { - $this->recorder = new DbTestRecorder( $this ); - $this->recorder->version = isset( $options['setversion'] ) ? - $options['setversion'] : SpecialVersion::getVersion(); - } elseif ( isset( $options['compare'] ) ) { - $this->recorder = new DbTestPreviewer( $this ); - } else { - $this->recorder = new TestRecorder( $this ); - } - } - - /** - * Remove last character if it is a newline - * @group utility - */ - static public function chomp( $s ) { - if ( substr( $s, -1 ) === "\n" ) { - return substr( $s, 0, -1 ); - } - else { - return $s; - } - } - - /** - * Run a fuzz test series - * Draw input from a set of test files - */ - function fuzzTest( $filenames ) { - $GLOBALS['wgContLang'] = Language::factory( 'en' ); - $dict = $this->getFuzzInput( $filenames ); - $dictSize = strlen( $dict ); - $logMaxLength = log( $this->maxFuzzTestLength ); - $this->setupDatabase(); - ini_set( 'memory_limit', $this->memoryLimit * 1048576 ); - - $numTotal = 0; - $numSuccess = 0; - $user = new User; - $opts = ParserOptions::newFromUser( $user ); - $title = Title::makeTitle( NS_MAIN, 'Parser_test' ); - - while ( true ) { - // Generate test input - mt_srand( ++$this->fuzzSeed ); - $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); - $input = ''; - - while ( strlen( $input ) < $totalLength ) { - $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; - $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); - $offset = mt_rand( 0, $dictSize - $hairLength ); - $input .= substr( $dict, $offset, $hairLength ); - } - - $this->setupGlobals(); - $parser = $this->getParser(); - - // Run the test - try { - $parser->parse( $input, $title, $opts ); - $fail = false; - } catch ( Exception $exception ) { - $fail = true; - } - - if ( $fail ) { - echo "Test failed with seed {$this->fuzzSeed}\n"; - echo "Input:\n"; - printf( "string(%d) \"%s\"\n\n", strlen( $input ), $input ); - echo "$exception\n"; - } else { - $numSuccess++; - } - - $numTotal++; - $this->teardownGlobals(); - $parser->__destruct(); - - if ( $numTotal % 100 == 0 ) { - $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 ); - echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n"; - if ( $usage > 90 ) { - echo "Out of memory:\n"; - $memStats = $this->getMemoryBreakdown(); - - foreach ( $memStats as $name => $usage ) { - echo "$name: $usage\n"; - } - $this->abort(); - } - } - } - } - - /** - * Get an input dictionary from a set of parser test files - */ - function getFuzzInput( $filenames ) { - $dict = ''; - - foreach ( $filenames as $filename ) { - $contents = file_get_contents( $filename ); - preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); - - foreach ( $matches[1] as $match ) { - $dict .= $match . "\n"; - } - } - - return $dict; - } - - /** - * Get a memory usage breakdown - */ - function getMemoryBreakdown() { - $memStats = array(); - - foreach ( $GLOBALS as $name => $value ) { - $memStats['$' . $name] = strlen( serialize( $value ) ); - } - - $classes = get_declared_classes(); - - foreach ( $classes as $class ) { - $rc = new ReflectionClass( $class ); - $props = $rc->getStaticProperties(); - $memStats[$class] = strlen( serialize( $props ) ); - $methods = $rc->getMethods(); - - foreach ( $methods as $method ) { - $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); - } - } - - $functions = get_defined_functions(); - - foreach ( $functions['user'] as $function ) { - $rf = new ReflectionFunction( $function ); - $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); - } - - asort( $memStats ); - - return $memStats; - } - - function abort() { - $this->abort(); - } - - /** - * Run a series of tests listed in the given text files. - * Each test consists of a brief description, wikitext input, - * and the expected HTML output. - * - * Prints status updates on stdout and counts up the total - * number and percentage of passed tests. - * - * @param $filenames Array of strings - * @return Boolean: true if passed all tests, false if any tests failed. - */ - public function runTestsFromFiles( $filenames ) { - $ok = false; - $GLOBALS['wgContLang'] = Language::factory( 'en' ); - $this->recorder->start(); - try { - $this->setupDatabase(); - $ok = true; - - foreach ( $filenames as $filename ) { - $tests = new TestFileIterator( $filename, $this ); - $ok = $this->runTests( $tests ) && $ok; - } - - $this->teardownDatabase(); - $this->recorder->report(); - } catch (DBError $e) { - echo $e->getMessage(); - } - $this->recorder->end(); - - return $ok; - } - - function runTests( $tests ) { - $ok = true; - - foreach ( $tests as $t ) { - $result = - $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] ); - $ok = $ok && $result; - $this->recorder->record( $t['test'], $result ); - } - - if ( $this->showProgress ) { - print "\n"; - } - - return $ok; - } - - /** - * Get a Parser object - */ - function getParser( $preprocessor = null ) { - global $wgParserConf; - - $class = $wgParserConf['class']; - $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); - - foreach ( $this->hooks as $tag => $callback ) { - $parser->setHook( $tag, $callback ); - } - - foreach ( $this->functionHooks as $tag => $bits ) { - list( $callback, $flags ) = $bits; - $parser->setFunctionHook( $tag, $callback, $flags ); - } - - wfRunHooks( 'ParserTestParser', array( &$parser ) ); - - return $parser; - } - - /** - * Run a given wikitext input through a freshly-constructed wiki parser, - * and compare the output against the expected results. - * Prints status and explanatory messages to stdout. - * - * @param $desc String: test's description - * @param $input String: wikitext to try rendering - * @param $result String: result to output - * @param $opts Array: test's options - * @param $config String: overrides for global variables, one per line - * @return Boolean - */ - public function runTest( $desc, $input, $result, $opts, $config ) { - if ( $this->showProgress ) { - $this->showTesting( $desc ); - } - - $opts = $this->parseOptions( $opts ); - $context = $this->setupGlobals( $opts, $config ); - - $user = $context->getUser(); - $options = ParserOptions::newFromContext( $context ); - - if ( isset( $opts['title'] ) ) { - $titleText = $opts['title']; - } - else { - $titleText = 'Parser test'; - } - - $local = isset( $opts['local'] ); - $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null; - $parser = $this->getParser( $preprocessor ); - $title = Title::newFromText( $titleText ); - - if ( isset( $opts['pst'] ) ) { - $out = $parser->preSaveTransform( $input, $title, $user, $options ); - } elseif ( isset( $opts['msg'] ) ) { - $out = $parser->transformMsg( $input, $options, $title ); - } elseif ( isset( $opts['section'] ) ) { - $section = $opts['section']; - $out = $parser->getSection( $input, $section ); - } elseif ( isset( $opts['replace'] ) ) { - $section = $opts['replace'][0]; - $replace = $opts['replace'][1]; - $out = $parser->replaceSection( $input, $section, $replace ); - } elseif ( isset( $opts['comment'] ) ) { - $out = Linker::formatComment( $input, $title, $local ); - } elseif ( isset( $opts['preload'] ) ) { - $out = $parser->getpreloadText( $input, $title, $options ); - } else { - $output = $parser->parse( $input, $title, $options, true, true, 1337 ); - $out = $output->getText(); - - if ( isset( $opts['showtitle'] ) ) { - if ( $output->getTitleText() ) { - $title = $output->getTitleText(); - } - - $out = "$title\n$out"; - } - - if ( isset( $opts['ill'] ) ) { - $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); - } elseif ( isset( $opts['cat'] ) ) { - $outputPage = $context->getOutput(); - $outputPage->addCategoryLinks( $output->getCategories() ); - $cats = $outputPage->getCategoryLinks(); - - if ( isset( $cats['normal'] ) ) { - $out = $this->tidy( implode( ' ', $cats['normal'] ) ); - } else { - $out = ''; - } - } - - $result = $this->tidy( $result ); - } - - $this->teardownGlobals(); - return $this->showTestResult( $desc, $result, $out ); - } - - /** - * - */ - function showTestResult( $desc, $result, $out ) { - if ( $result === $out ) { - $this->showSuccess( $desc ); - return true; - } else { - $this->showFailure( $desc, $result, $out ); - return false; - } - } - - /** - * Use a regex to find out the value of an option - * @param $key String: name of option val to retrieve - * @param $opts Options array to look in - * @param $default Mixed: default value returned if not found - */ - private static function getOptionValue( $key, $opts, $default ) { - $key = strtolower( $key ); - - if ( isset( $opts[$key] ) ) { - return $opts[$key]; - } else { - return $default; - } - } - - private function parseOptions( $instring ) { - $opts = array(); - // foo - // foo=bar - // foo="bar baz" - // foo=[[bar baz]] - // foo=bar,"baz quux" - $regex = '/\b - ([\w-]+) # Key - \b - (?:\s* - = # First sub-value - \s* - ( - " - [^"]* # Quoted val - " - | - \[\[ - [^]]* # Link target - \]\] - | - [\w-]+ # Plain word - ) - (?:\s* - , # Sub-vals 1..N - \s* - ( - "[^"]*" # Quoted val - | - \[\[[^]]*\]\] # Link target - | - [\w-]+ # Plain word - ) - )* - )? - /x'; - - if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) { - foreach ( $matches as $bits ) { - array_shift( $bits ); - $key = strtolower( array_shift( $bits ) ); - if ( count( $bits ) == 0 ) { - $opts[$key] = true; - } elseif ( count( $bits ) == 1 ) { - $opts[$key] = $this->cleanupOption( array_shift( $bits ) ); - } else { - // Array! - $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits ); - } - } - } - return $opts; - } - - private function cleanupOption( $opt ) { - if ( substr( $opt, 0, 1 ) == '"' ) { - return substr( $opt, 1, -1 ); - } - - if ( substr( $opt, 0, 2 ) == '[[' ) { - return substr( $opt, 2, -2 ); - } - return $opt; - } - - /** - * Set up the global variables for a consistent environment for each test. - * Ideally this should replace the global configuration entirely. - */ - private function setupGlobals( $opts = '', $config = '' ) { - # Find out values for some special options. - $lang = - self::getOptionValue( 'language', $opts, 'en' ); - $variant = - self::getOptionValue( 'variant', $opts, false ); - $maxtoclevel = - self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); - $linkHolderBatchSize = - self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); - - $settings = array( - 'wgServer' => 'http://Britney-Spears', - 'wgScript' => '/index.php', - 'wgScriptPath' => '/', - 'wgArticlePath' => '/wiki/$1', - 'wgActionPaths' => array(), - 'wgLockManagers' => array( - 'name' => 'fsLockManager', - 'class' => 'FSLockManager', - 'lockDirectory' => $this->uploadDir . '/lockdir', - ), - 'wgLocalFileRepo' => array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'local-public' => $this->uploadDir, - 'local-thumb' => $this->uploadDir . '/thumb', - 'local-temp' => $this->uploadDir . '/temp', - 'local-deleted' => $this->uploadDir . '/delete', - ) - ) ) - ), - 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgStylePath' => '/skins', - 'wgStyleSheetPath' => '/skins', - 'wgSitename' => 'MediaWiki', - 'wgLanguageCode' => $lang, - 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'parsertest_' : 'pt_', - 'wgRawHtml' => isset( $opts['rawhtml'] ), - 'wgLang' => null, - 'wgContLang' => null, - 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ), - 'wgMaxTocLevel' => $maxtoclevel, - 'wgCapitalLinks' => true, - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgThumbnailScriptPath' => false, - 'wgUseImageResize' => false, - 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, - 'wgUseTidy' => false, - 'wgDefaultLanguageVariant' => $variant, - 'wgVariantArticlePath' => false, - 'wgGroupPermissions' => array( '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ), - 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ), - 'wgDefaultExternalStore' => array(), - 'wgForeignFileRepos' => array(), - 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - 'wgExperimentalHtmlIds' => false, - 'wgExternalLinkTarget' => false, - 'wgAlwaysUseTidy' => false, - 'wgHtml5' => true, - 'wgWellFormedXml' => true, - 'wgAllowMicrodataAttributes' => true, - 'wgAdaptiveMessageCache' => true, - 'wgDisableLangConversion' => false, - 'wgDisableTitleConversion' => false, - ); - - if ( $config ) { - $configLines = explode( "\n", $config ); - - foreach ( $configLines as $line ) { - list( $var, $value ) = explode( '=', $line, 2 ); - - $settings[$var] = eval( "return $value;" ); - } - } - - $this->savedGlobals = array(); - - /** @since 1.20 */ - wfRunHooks( 'ParserTestGlobals', array( &$settings ) ); - - foreach ( $settings as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedGlobals[$var] = $GLOBALS[$var]; - } - - $GLOBALS[$var] = $val; - } - - $GLOBALS['wgContLang'] = Language::factory( $lang ); - $GLOBALS['wgMemc'] = new EmptyBagOStuff; - - $context = new RequestContext(); - $GLOBALS['wgLang'] = $context->getLanguage(); - $GLOBALS['wgOut'] = $context->getOutput(); - - $GLOBALS['wgUser'] = new User(); - - global $wgHooks; - - $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; - $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; - - MagicWord::clearCache(); - - return $context; - } - - /** - * List of temporary tables to create, without prefix. - * Some of these probably aren't necessary. - */ - private function listTables() { - $tables = array( 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions', - 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks', - 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks', - 'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage', - 'recentchanges', 'watchlist', 'interwiki', 'logging', - 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo', - 'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links' - ); - - if ( in_array( $this->db->getType(), array( 'mysql', 'sqlite', 'oracle' ) ) ) { - array_push( $tables, 'searchindex' ); - } - - // Allow extensions to add to the list of tables to duplicate; - // may be necessary if they hook into page save or other code - // which will require them while running tests. - wfRunHooks( 'ParserTestTables', array( &$tables ) ); - - return $tables; - } - - /** - * Set up a temporary set of wiki tables to work with for the tests. - * Currently this will only be done once per run, and any changes to - * the db will be visible to later tests in the run. - */ - public function setupDatabase() { - global $wgDBprefix; - - if ( $this->databaseSetupDone ) { - return; - } - - $this->db = wfGetDB( DB_MASTER ); - $dbType = $this->db->getType(); - - if ( $wgDBprefix === 'parsertest_' || ( $dbType == 'oracle' && $wgDBprefix === 'pt_' ) ) { - throw new MWException( 'setupDatabase should be called before setupGlobals' ); - } - - $this->databaseSetupDone = true; - $this->oldTablePrefix = $wgDBprefix; - - # SqlBagOStuff broke when using temporary tables on r40209 (bug 15892). - # It seems to have been fixed since (r55079?), but regressed at some point before r85701. - # This works around it for now... - ObjectCache::$instances[CACHE_DB] = new HashBagOStuff; - - # CREATE TEMPORARY TABLE breaks if there is more than one server - if ( wfGetLB()->getServerCount() != 1 ) { - $this->useTemporaryTables = false; - } - - $temporary = $this->useTemporaryTables || $dbType == 'postgres'; - $prefix = $dbType != 'oracle' ? 'parsertest_' : 'pt_'; - - $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix ); - $this->dbClone->useTemporaryTables( $temporary ); - $this->dbClone->cloneTableStructure(); - - if ( $dbType == 'oracle' ) { - $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' ); - # Insert 0 user to prevent FK violations - - # Anonymous user - $this->db->insert( 'user', array( - 'user_id' => 0, - 'user_name' => 'Anonymous' ) ); - } - - # Hack: insert a few Wikipedia in-project interwiki prefixes, - # for testing inter-language links - $this->db->insert( 'interwiki', array( - array( 'iw_prefix' => 'wikipedia', - 'iw_url' => 'http://en.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'meatball', - 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'zh', - 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'es', - 'iw_url' => 'http://es.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'fr', - 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'ru', - 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - ) ); - - # Update certain things in site_stats - $this->db->insert( 'site_stats', array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) ); - - # Reinitialise the LocalisationCache to match the database state - Language::getLocalisationCache()->unloadAll(); - - # Clear the message cache - MessageCache::singleton()->clear(); - - $this->uploadDir = $this->setupUploadDir(); - $user = User::createNew( 'WikiSysop' ); - $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); - $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array( - 'size' => 12345, - 'width' => 1941, - 'height' => 220, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), - 'fileExists' => true - ), $this->db->timestamp( '20010115123500' ), $user ); - - # This image will be blacklisted in [[MediaWiki:Bad image list]] - $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) ); - $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', array( - 'size' => 12345, - 'width' => 320, - 'height' => 240, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), - 'fileExists' => true - ), $this->db->timestamp( '20010115123500' ), $user ); - } - - public function teardownDatabase() { - if ( !$this->databaseSetupDone ) { - $this->teardownGlobals(); - return; - } - $this->teardownUploadDir( $this->uploadDir ); - - $this->dbClone->destroy(); - $this->databaseSetupDone = false; - - if ( $this->useTemporaryTables ) { - if( $this->db->getType() == 'sqlite' ) { - # Under SQLite the searchindex table is virtual and need - # to be explicitly destroyed. See bug 29912 - # See also MediaWikiTestCase::destroyDB() - wfDebug( __METHOD__ . " explicitly destroying sqlite virtual table parsertest_searchindex\n" ); - $this->db->query( "DROP TABLE `parsertest_searchindex`" ); - } - # Don't need to do anything - $this->teardownGlobals(); - return; - } - - $tables = $this->listTables(); - - foreach ( $tables as $table ) { - $sql = $this->db->getType() == 'oracle' ? "DROP TABLE pt_$table DROP CONSTRAINTS" : "DROP TABLE `parsertest_$table`"; - $this->db->query( $sql ); - } - - if ( $this->db->getType() == 'oracle' ) - $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' ); - - $this->teardownGlobals(); - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - private function setupUploadDir() { - global $IP; - - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - // wfDebug( "Creating upload directory $dir\n" ); - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - return $dir; - } - - wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); - wfMkdirParents( $dir . '/0/09', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - - return $dir; - } - - /** - * Restore default values and perform any necessary clean-up - * after each test runs. - */ - private function teardownGlobals() { - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - LockManagerGroup::destroySingleton(); - LinkCache::singleton()->clear(); - - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - } - - /** - * Remove the dummy uploads directory - */ - private function teardownUploadDir( $dir ) { - if ( $this->keepUploads ) { - return; - } - - // delete the files first, then the dirs. - self::deleteFiles( - array ( - "$dir/3/3a/Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$dir/0/09/Bad.jpg", - - "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", - ) - ); - - self::deleteDirs( - array ( - "$dir/3/3a", - "$dir/3", - "$dir/thumb/6/65", - "$dir/thumb/6", - "$dir/thumb/3/3a/Foobar.jpg", - "$dir/thumb/3/3a", - "$dir/thumb/3", - - "$dir/0/09/", - "$dir/0/", - "$dir/thumb", - "$dir/math/f/a/5", - "$dir/math/f/a", - "$dir/math/f", - "$dir/math", - "$dir", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - foreach ( $files as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); - } - } - } - - /** - * Delete the specified directories, if they exist. Must be empty. - * @param $dirs Array: full paths to directories to delete. - */ - private static function deleteDirs( $dirs ) { - foreach ( $dirs as $dir ) { - if ( is_dir( $dir ) ) { - rmdir( $dir ); - } - } - } - - /** - * "Running test $desc..." - */ - protected function showTesting( $desc ) { - print "Running test $desc... "; - } - - /** - * Print a happy success message. - * - * @param $desc String: the test name - * @return Boolean - */ - protected function showSuccess( $desc ) { - if ( $this->showProgress ) { - print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n"; - } - - return true; - } - - /** - * Print a failure message and provide some explanatory output - * about what went wrong if so configured. - * - * @param $desc String: the test name - * @param $result String: expected HTML output - * @param $html String: actual HTML output - * @return Boolean - */ - protected function showFailure( $desc, $result, $html ) { - if ( $this->showFailure ) { - if ( !$this->showProgress ) { - # In quiet mode we didn't show the 'Testing' message before the - # test, in case it succeeded. Show it now: - $this->showTesting( $desc ); - } - - print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n"; - - if ( $this->showOutput ) { - print "--- Expected ---\n$result\n--- Actual ---\n$html\n"; - } - - if ( $this->showDiffs ) { - print $this->quickDiff( $result, $html ); - if ( !$this->wellFormed( $html ) ) { - print "XML error: $this->mXmlError\n"; - } - } - } - - return false; - } - - /** - * Run given strings through a diff and return the (colorized) output. - * Requires writable /tmp directory and a 'diff' command in the PATH. - * - * @param $input String - * @param $output String - * @param $inFileTail String: tailing for the input file name - * @param $outFileTail String: tailing for the output file name - * @return String - */ - protected function quickDiff( $input, $output, $inFileTail = 'expected', $outFileTail = 'actual' ) { - # Windows, or at least the fc utility, is retarded - $slash = wfIsWindows() ? '\\' : '/'; - $prefix = wfTempDir() . "{$slash}mwParser-" . mt_rand(); - - $infile = "$prefix-$inFileTail"; - $this->dumpToFile( $input, $infile ); - - $outfile = "$prefix-$outFileTail"; - $this->dumpToFile( $output, $outfile ); - - $shellInfile = wfEscapeShellArg($infile); - $shellOutfile = wfEscapeShellArg($outfile); - - global $wgDiff3; - // we assume that people with diff3 also have usual diff - $diff = ( wfIsWindows() && !$wgDiff3 ) - ? `fc $shellInfile $shellOutfile` - : `diff -au $shellInfile $shellOutfile`; - unlink( $infile ); - unlink( $outfile ); - - return $this->colorDiff( $diff ); - } - - /** - * Write the given string to a file, adding a final newline. - * - * @param $data String - * @param $filename String - */ - private function dumpToFile( $data, $filename ) { - $file = fopen( $filename, "wt" ); - fwrite( $file, $data . "\n" ); - fclose( $file ); - } - - /** - * Colorize unified diff output if set for ANSI color output. - * Subtractions are colored blue, additions red. - * - * @param $text String - * @return String - */ - protected function colorDiff( $text ) { - return preg_replace( - array( '/^(-.*)$/m', '/^(\+.*)$/m' ), - array( $this->term->color( 34 ) . '$1' . $this->term->reset(), - $this->term->color( 31 ) . '$1' . $this->term->reset() ), - $text ); - } - - /** - * Show "Reading tests from ..." - * - * @param $path String - */ - public function showRunFile( $path ) { - print $this->term->color( 1 ) . - "Reading tests from \"$path\"..." . - $this->term->reset() . - "\n"; - } - - /** - * Insert a temporary test article - * @param $name String: the title, including any prefix - * @param $text String: the article text - * @param $line Integer: the input line number, for reporting errors - * @param $ignoreDuplicate Boolean: whether to silently ignore duplicate pages - */ - static public function addArticle( $name, $text, $line = 'unknown', $ignoreDuplicate = '' ) { - global $wgCapitalLinks; - - $oldCapitalLinks = $wgCapitalLinks; - $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637 - - $text = self::chomp( $text ); - $name = self::chomp( $name ); - - $title = Title::newFromText( $name ); - - if ( is_null( $title ) ) { - throw new MWException( "invalid title '$name' at line $line\n" ); - } - - $page = WikiPage::factory( $title ); - $page->loadPageData( 'fromdbmaster' ); - - if ( $page->exists() ) { - if ( $ignoreDuplicate == 'ignoreduplicate' ) { - return; - } else { - throw new MWException( "duplicate article '$name' at line $line\n" ); - } - } - - $page->doEdit( $text, '', EDIT_NEW ); - - $wgCapitalLinks = $oldCapitalLinks; - } - - /** - * Steal a callback function from the primary parser, save it for - * application to our scary parser. If the hook is not installed, - * abort processing of this file. - * - * @param $name String - * @return Bool true if tag hook is present - */ - public function requireHook( $name ) { - global $wgParser; - - $wgParser->firstCallInit( ); // make sure hooks are loaded. - - if ( isset( $wgParser->mTagHooks[$name] ) ) { - $this->hooks[$name] = $wgParser->mTagHooks[$name]; - } else { - echo " This test suite requires the '$name' hook extension, skipping.\n"; - return false; - } - - return true; - } - - /** - * Steal a callback function from the primary parser, save it for - * application to our scary parser. If the hook is not installed, - * abort processing of this file. - * - * @param $name String - * @return Bool true if function hook is present - */ - public function requireFunctionHook( $name ) { - global $wgParser; - - $wgParser->firstCallInit( ); // make sure hooks are loaded. - - if ( isset( $wgParser->mFunctionHooks[$name] ) ) { - $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name]; - } else { - echo " This test suite requires the '$name' function hook extension, skipping.\n"; - return false; - } - - return true; - } - - /** - * Run the "tidy" command on text if the $wgUseTidy - * global is true - * - * @param $text String: the text to tidy - * @return String - */ - private function tidy( $text ) { - global $wgUseTidy; - - if ( $wgUseTidy ) { - $text = MWTidy::tidy( $text ); - } - - return $text; - } - - private function wellFormed( $text ) { - $html = - Sanitizer::hackDocType() . - '' . - $text . - ''; - - $parser = xml_parser_create( "UTF-8" ); - - # case folding violates XML standard, turn it off - xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); - - if ( !xml_parse( $parser, $html, true ) ) { - $err = xml_error_string( xml_get_error_code( $parser ) ); - $position = xml_get_current_byte_index( $parser ); - $fragment = $this->extractFragment( $html, $position ); - $this->mXmlError = "$err at byte $position:\n$fragment"; - xml_parser_free( $parser ); - - return false; - } - - xml_parser_free( $parser ); - - return true; - } - - private function extractFragment( $text, $position ) { - $start = max( 0, $position - 10 ); - $before = $position - $start; - $fragment = '...' . - $this->term->color( 34 ) . - substr( $text, $start, $before ) . - $this->term->color( 0 ) . - $this->term->color( 31 ) . - $this->term->color( 1 ) . - substr( $text, $position, 1 ) . - $this->term->color( 0 ) . - $this->term->color( 34 ) . - substr( $text, $position + 1, 9 ) . - $this->term->color( 0 ) . - '...'; - $display = str_replace( "\n", ' ', $fragment ); - $caret = ' ' . - str_repeat( ' ', $before ) . - $this->term->color( 31 ) . - '^' . - $this->term->color( 0 ); - - return "$display\n$caret"; - } - - static function getFakeTimestamp( &$parser, &$ts ) { - $ts = 123; - return true; - } -} diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt deleted file mode 100644 index df057248..00000000 --- a/tests/parser/parserTests.txt +++ /dev/null @@ -1,10363 +0,0 @@ -# MediaWiki Parser test cases -# Some taken from http://meta.wikimedia.org/wiki/Parser_testing -# All (C) their respective authors and released under the GPL -# -# The syntax should be fairly self-explanatory. -# -# Currently supported test options: -# One of the following three: -# -# (default) generate HTML output -# pst apply pre-save transform -# msg apply message transform -# -# Plus any combination of these: -# -# cat add category links -# ill add inter-language links -# subpage enable subpages (disabled by default) -# noxml don't check for XML well formdness -# title=[[XXX]] run test using article title XXX -# language=XXX set content language to XXX for this test -# variant=XXX set the variant of language for this test (eg zh-tw) -# disabled do not run test -# showtitle make the first line the title -# comment run through Linker::formatComment() instead of main parser -# local format section links in edit comment text as local links -# -# For testing purposes, temporary articles can created: -# !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle -# where '/' denotes a newline. - -# This is the standard article assumed to exist. -!! article -Main Page -!! text -blah blah -!! endarticle - -!!article -Template:Foo -!!text -FOO -!!endarticle - -!! article -Template:Blank -!! text -!! endarticle - -!! article -Template:! -!! text -| -!! endarticle - -!!article -MediaWiki:bad image list -!!text -* [[File:Bad.jpg]] except [[Nasty page]] -!!endarticle - -!! article -Template:inner list -!! text -* item 1 -!! endarticle - -### -### Basic tests -### -!! test -Blank input -!! input -!! result -!! end - - -!! test -Simple paragraph -!! input -This is a simple paragraph. -!! result -

This is a simple paragraph. -

-!! end - -!! test -Paragraphs with extra newline spacing -!! input -foo - -bar - - -baz - - - -booz -!! result -

foo -

bar -


-baz -


-

booz -

-!! end - -!! test -Simple list -!! input -* Item 1 -* Item 2 -!! result -
  • Item 1 -
  • Item 2 -
- -!! end - -!! test -Italics and bold -!! input -* plain -* plain''italic''plain -* plain''italic''plain''italic''plain -* plain'''bold'''plain -* plain'''bold'''plain'''bold'''plain -* plain''italic''plain'''bold'''plain -* plain'''bold'''plain''italic''plain -* plain''italic'''bold-italic'''italic''plain -* plain'''bold''bold-italic''bold'''plain -* plain'''''bold-italic'''italic''plain -* plain'''''bold-italic''bold'''plain -* plain''italic'''bold-italic'''''plain -* plain'''bold''bold-italic'''''plain -* plain l'''italic''plain -* plain l''''bold''' plain -!! result -
  • plain -
  • plainitalicplain -
  • plainitalicplainitalicplain -
  • plainboldplain -
  • plainboldplainboldplain -
  • plainitalicplainboldplain -
  • plainboldplainitalicplain -
  • plainitalicbold-italicitalicplain -
  • plainboldbold-italicboldplain -
  • plainbold-italicitalicplain -
  • plainbold-italicboldplain -
  • plainitalicbold-italicplain -
  • plainboldbold-italicplain -
  • plain l'italicplain -
  • plain l'bold plain -
- -!! end - -### -### 2-quote opening sequence tests -### -!! test -Italics and bold: 2-quote opening sequence: (2,2) -!! input -''foo'' -!! result -

foo -

-!!end - - -!! test -Italics and bold: 2-quote opening sequence: (2,3) -!! input -''foo''' -!! result -

foo' -

-!!end - - -!! test -Italics and bold: 2-quote opening sequence: (2,4) -!! input -''foo'''' -!! result -

foo'' -

-!!end - - -!! test -Italics and bold: 2-quote opening sequence: (2,5) -!! input -''foo''''' -!! result -

foo -

-!!end - - -### -### 3-quote opening sequence tests -### - -!! test -Italics and bold: 3-quote opening sequence: (3,2) -!! input -'''foo'' -!! result -

'foo -

-!!end - - -!! test -Italics and bold: 3-quote opening sequence: (3,3) -!! input -'''foo''' -!! result -

foo -

-!!end - - -!! test -Italics and bold: 3-quote opening sequence: (3,4) -!! input -'''foo'''' -!! result -

foo' -

-!!end - - -!! test -Italics and bold: 3-quote opening sequence: (3,5) -!! input -'''foo''''' -!! result -

foo -

-!!end - - -### -### 4-quote opening sequence tests -### - -!! test -Italics and bold: 4-quote opening sequence: (4,2) -!! input -''''foo'' -!! result -

''foo -

-!!end - - -!! test -Italics and bold: 4-quote opening sequence: (4,3) -!! input -''''foo''' -!! result -

'foo -

-!!end - - -!! test -Italics and bold: 4-quote opening sequence: (4,4) -!! input -''''foo'''' -!! result -

'foo' -

-!!end - - -!! test -Italics and bold: 4-quote opening sequence: (4,5) -!! input -''''foo''''' -!! result -

'foo -

-!!end - - -### -### 5-quote opening sequence tests -### - -!! test -Italics and bold: 5-quote opening sequence: (5,2) -!! input -'''''foo'' -!! result -

foo -

-!!end - - -!! test -Italics and bold: 5-quote opening sequence: (5,3) -!! input -'''''foo''' -!! result -

foo -

-!!end - - -!! test -Italics and bold: 5-quote opening sequence: (5,4) -!! input -'''''foo'''' -!! result -

foo' -

-!!end - - -!! test -Italics and bold: 5-quote opening sequence: (5,5) -!! input -'''''foo''''' -!! result -

foo -

-!!end - -### -### multiple quote sequences in a line -### -!! test -Italics and bold: multiple quote sequences: (2,4,2) -!! input -''foo''''bar'' -!! result -

foo'bar -

-!!end - - -!! test -Italics and bold: multiple quote sequences: (2,4,3) -!! input -''foo''''bar''' -!! result -

foo'bar -

-!!end - - -!! test -Italics and bold: multiple quote sequences: (2,4,4) -!! input -''foo''''bar'''' -!! result -

foo'bar' -

-!!end - - -!! test -Italics and bold: multiple quote sequences: (3,4,2) -!! input -'''foo''''bar'' -!! result -

foo'bar -

-!!end - - -!! test -Italics and bold: multiple quote sequences: (3,4,3) -!! input -'''foo''''bar''' -!! result -

foo'bar -

-!!end - -### -### other quote tests -### -!! test -Italics and bold: other quote tests: (2,3,5) -!! input -''this is about '''foo's family''''' -!! result -

this is about foo's family -

-!!end - - -!! test -Italics and bold: other quote tests: (2,(3,3),2) -!! input -''this is about '''foo's''' family'' -!! result -

this is about foo's family -

-!!end - - -!! test -Italics and bold: other quote tests: (3,2,3,2) -!! input -'''this is about ''foo'''s family'' -!! result -

this is about foos family -

-!!end - - -!! test -Italics and bold: other quote tests: (3,2,3,3) -!! input -'''this is about ''foo'''s family''' -!! result -

'this is about foos family -

-!!end - - - -!! test -Italics and bold: other quote tests: (3,(2,2),3) -!! input -'''this is about ''foo's'' family''' -!! result -

this is about foo's family -

-!!end - -### -### test cases -### - -!! test - unordered list -!! input -* This is not an unordered list item. -!! result -

* This is not an unordered list item. -

-!! end - -!! test - spacing -!! input -Lorem ipsum dolor - -sed abit. - sed nullum. - -:and a colon - -!! result -

Lorem ipsum dolor - -sed abit. - sed nullum. - -:and a colon - -

-!! end - -!! test -nowiki 3 -!! input -:There is not nowiki. -:There is nowiki. - -#There is not nowiki. -#There is nowiki. - -*There is not nowiki. -*There is nowiki. -!! result -
There is not nowiki. -
There is nowiki. -
-
  1. There is not nowiki. -
  2. There is nowiki. -
-
  • There is not nowiki. -
  • There is nowiki. -
- -!! end - - -### -### Comments -### -!! test -Comment test 1 -!! input - asdf - -!! result -
asdf
-
- -!! end - -!! test -Comment test 2 -!! input -asdf - -jkl -!! result -

asdf -jkl -

-!! end - -!! test -Comment test 3 -!! input -asdf - - -jkl -!! result -

asdf -jkl -

-!! end - -!! test -Comment test 4 -!! input -asdfjkl -!! result -

asdfjkl -

-!! end - -!! test -Comment spacing -!! input -a - b -c -!! result -

a -

-
 b 
-
-

c -

-!! end - -!! test -Comment whitespace -!! input - -!! result - -!! end - -!! test -Comment semantics and delimiters -!! input - -!! result - -!! end - -!! test -Comment semantics and delimiters, redux -!! input - -!! result - -!! end - -!! test -Comment semantics and delimiters: directors cut -!! input ---> -!! result -

--> -

-!! end - -!! test -Comment semantics: nesting -!! input ---> -!! result -

--> -

-!! end - -!! test -Comment semantics: unclosed comment at end -!! input -oo}} -!! result -

FOO -

-!! end - -!! test -Comment on its own line post-expand -!! input -a -{{blank}} -b -!! result -

a -

b -

-!! end - -### -### Preformatted text -### -!! test -Preformatted text -!! input - This is some - Preformatted text - With ''italic'' - And '''bold''' - And a [[Main Page|link]] -!! result -
This is some
-Preformatted text
-With italic
-And bold
-And a link
-
-!! end - -!! test -
 with  inside (compatibility with 1.6 and earlier)
-!! input
-

-
-
-
-
-!! result -
-<b>
-<cite>
-<em>
-
- -!! end - -!! test -Regression with preformatted in
-!! input -
- Blah -
-!! result -
-
Blah
-
-
- -!! end - -# Expected output in the following test is not really expected (there should be -#
 in the output) -- it's only testing for well-formedness.
-!! test
-Bug 6200: Preformatted in 
-!! input -
- Blah -
-!! result -
- Blah -
- -!! end - -!! test -
 with attributes (bug 3202)
-!! input
-
Bluescreen of WikiDeath
-!! result -
Bluescreen of WikiDeath
- -!! end - -!! test -
 with width attribute (bug 3202)
-!! input
-
Narrow screen goodies
-!! result -
Narrow screen goodies
- -!! end - -!! test -
 with forbidden attribute (bug 3202)
-!! input
-
Narrow screen goodies
-!! result -
Narrow screen goodies
- -!! end - -!! test -
 with forbidden attribute values (bug 3202)
-!! input
-
Narrow screen goodies
-!! result -
Narrow screen goodies
- -!! end - -!! test - inside
 (bug 13238)
-!! input
-
-
-
-
-
-
-
Foo
-!! result -
-<nowiki>
-
-
-
-
-
<nowiki>Foo</nowiki>
- -!! end - -!! test - and
 preference (first one wins)
-!! input
-
-
-
- -
- - -
-
-
-
-
- -!! result -
-<nowiki>
-
-

</nowiki> -</pre> -

-<pre> -<nowiki> -</pre> - -</pre> -

-!! end - - -### -### Definition lists -### -!! test -Simple definition -!! input -; name : Definition -!! result -
name 
Definition -
- -!! end - -!! test -Definition list for indentation only -!! input -: Indented text -!! result -
Indented text -
- -!! end - -!! test -Definition list with no space -!! input -;name:Definition -!! result -
name
Definition -
- -!!end - -!! test -Definition list with URL link -!! input -; http://example.com/ : definition -!! result -
http://example.com/ 
definition -
- -!! end - -!! test -Definition list with bracketed URL link -!! input -;[http://www.example.com/ Example]:Something about it -!! result -
Example
Something about it -
- -!! end - -!! test -Definition list with wikilink containing colon -!! input -; [[Help:FAQ]]: The least-read page on Wikipedia -!! result -
Help:FAQ
The least-read page on Wikipedia -
- -!! end - -# At Brion's and JeLuF's insistence... :) -!! test -Definition list with news link containing colon -!! input -; news:alt.wikipedia.rox: This isn't even a real newsgroup! -!! result -
news:alt.wikipedia.rox
This isn't even a real newsgroup! -
- -!! end - -!! test -Malformed definition list with colon -!! input -; news:alt.wikipedia.rox -- don't crash or enter an infinite loop -!! result -
news:alt.wikipedia.rox -- don't crash or enter an infinite loop -
- -!! end - -!! test -Definition lists: colon in external link text -!! input -; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up -!! result -
Wikipedia : The Next Generation
OK, I made that up -
- -!! end - -!! test -Definition lists: colon in HTML attribute -!! input -;bold -!! result -
bold -
- -!! end - - -!! test -Definition lists: self-closed tag -!! input -;one
two : two-line fun -!! result -
one
two 
two-line fun -
- -!! end - -!! test -Bug 11748: Literal closing tags -!! options -disabled -!! input -
-
test 1
-
test test test test test
-
test 2
-
test test test test test
-
-!! result -
-
test 1
-
test test test test test
-
test 2
-
test test test test test
-
-!! end - -!! test -Definition and unordered list using wiki syntax nested in unordered list using html tags. -!! input -
  • -; term : description -* unordered -
  • -
-!! result -
  • -
    term 
    description -
    -
    • unordered -
    -
  • -
- -!! end - -!! test -Definition list with empty definition and following paragraph -!! input -; term: -Paragraph text -!! result -
term
-
-

Paragraph text -

-!! end - -!! test -Definition Lists: No nesting: Multiple dd's -!! input -;x -:a -:b -!! result -
x -
a -
b -
- -!! end - -!! test -Definition Lists: Indentation: Regular -!! input -:i1 -::i2 -:::i3 -!! result -
i1 -
i2 -
i3 -
-
-
- -!! end - -!! test -Definition Lists: Indentation: Missing 1st level -!! input -::i2 -:::i3 -!! result -
i2 -
i3 -
-
-
- -!! end - -!! test -Definition Lists: Indentation: Multi-level indent -!! input -:::i3 -!! result -
i3 -
-
-
- -!! end - -## The PHP parser treats : items (dd) without a corresponding ; item (dt) -## as an empty dt item. It also ignores all but the last ";" when followed -## by ":" later on. So, ";" are not ignored in ";;;t3" but are ignored in -## ";;;t3 :d1". So, PHP parser behavior is a little inconsistent wrt multiple -## ";"s. -## -## Ex: ";;t2 ::d2" is transformed into: -## -##
-##
t2
-##
-##
-##
-##
d2
-##
-##
-##
-## -## But, Parsoid treats "; :" as a tight atomic unit and excess ":" as plain text -## So, the same wikitext above (;;t2 ::d2) is transformed into: -## -##
-##
-##
-##
t2
-##
:d2
-##
-##
-##
-## -## All Parsoid only definition list tests have this difference. -## -## See also: https://bugzilla.wikimedia.org/show_bug.cgi?id=6569 -## and http://lists.wikimedia.org/pipermail/wikitext-l/2011-November/000483.html - -!! test -Definition Lists: Nesting: Multi-level (Parsoid only) -!! options -disabled -!! input -;t1 :d1 -;;t2 ::d2 -;;;t3 :::d3 -!! result -
-
t1
-
d1
-
-
-
t2
-
:d2
-
-
-
t3
-
::d3
-
-
-
-
-
- - -!! end - - -!! test -Definition Lists: Nesting: Test 2 (Parsoid only) -!! options -disabled -!! input -;t1 -::d2 -!! result -
-
t1
-
-
-
d2
-
-
-
- -!! end - - -!! test -Definition Lists: Nesting: Test 3 (Parsoid only) -!! options -disabled -!! input -:;t1 -::::d2 -!! result -
-
-
-
t1
-
-
-
-
-
d2
-
-
-
-
-
-
-
- -!! end - - -!! test -Definition Lists: Nesting: Test 4 -!! input -::;t3 -:::d3 -!! result -
t3 -
d3 -
-
-
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 1 -!! input -:;* foo -::* bar -:; baz -!! result -
  • foo -
  • bar -
-
-
baz -
-
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 2 -!! input -*: d1 -*: d2 -!! result -
  • d1 -
    d2 -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 3 -!! input -*::: d1 -*::: d2 -!! result -
  • d1 -
    d2 -
    -
    -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 4 -!! input -*;d1 :d2 -*;d3 :d4 -!! result -
  • d1 
    d2 -
    d3 
    d4 -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 5 -!! input -*:d1 -*:: d2 -!! result -
  • d1 -
    d2 -
    -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 6 -!! input -#*:d1 -#*::: d3 -!! result -
    • d1 -
      d3 -
      -
      -
      -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 7 -!! input -:* d1 -:* d2 -!! result -
  • d1 -
  • d2 -
-
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 8 -!! input -:* d1 -::* d2 -!! result -
  • d1 -
-
  • d2 -
-
-
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 9 -!! input -*;foo :bar -!! result -
  • foo 
    bar -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 10 -!! input -*#;foo :bar -!! result -
    1. foo 
      bar -
      -
    -
- -!! end - - -!! test -Definition Lists: Mixed Lists: Test 11 -!! input -*#*#;*;;foo :bar -*#*#;boo :baz -!! result -
        1. foo 
          • bar -
            -
          -
      - -
      boo 
      baz -
      -
    -
- - - -!! end - - -!! test -Definition Lists: Weird Ones: Test 1 -!! input -*#;*::;; foo : bar (who uses this?) -!! result -
    1. foo 
      • bar (who uses this?) -
        -
        -
        -
      -
- - - - -!! end - -### -### External links -### -!! test -External links: non-bracketed -!! input -Non-bracketed: http://example.com -!! result -

Non-bracketed: http://example.com -

-!! end - -!! test -External links: numbered -!! input -Numbered: [http://example.com] -Numbered: [http://example.net] -Numbered: [http://example.com] -!! result -

Numbered: [1] -Numbered: [2] -Numbered: [3] -

-!!end - -!! test -External links: specified text -!! input -Specified text: [http://example.com link] -!! result -

Specified text: link -

-!!end - -!! test -External links: trail -!! input -Linktrails should not work for external links: [http://example.com link]s -!! result -

Linktrails should not work for external links: links -

-!! end - -!! test -External links: dollar sign in URL -!! input -http://example.com/1$2345 -!! result -

http://example.com/1$2345 -

-!! end - -!! test -External links: dollar sign in URL (named) -!! input -[http://example.com/1$2345] -!! result -

[1] -

-!!end - -!! test -External links: open square bracket forbidden in URL (bug 4377) -!! input -http://example.com/1[2345 -!! result -

http://example.com/1[2345 -

-!! end - -!! test -External links: open square bracket forbidden in URL (named) (bug 4377) -!! input -[http://example.com/1[2345] -!! result -

[2345 -

-!!end - -!! test -External links: nowiki in URL link text (bug 6230) -!!input -[http://example.com/ ''example site''] -!! result -

''example site'' -

-!! end - -!! test -External links: newline forbidden in text (bug 6230 regression check) -!! input -[http://example.com/ first -second] -!! result -

[http://example.com/ first -second] -

-!!end - -!! test -External links: protocol-relative URL in brackets -!! input -[//example.com/ Test] -!! result -

Test -

-!! end - -!! test -External links: protocol-relative URL in brackets without text -!! input -[//example.com] -!! result -

[1] -

-!! end - -!! test -External links: protocol-relative URL in free text is left alone -!! input -//example.com/Foo -!! result -

//example.com/Foo -

-!!end - -!! test -External links: protocol-relative URL in the middle of a word is left alone (bug 30269) -!! input -foo//example.com/Foo -!! result -

foo//example.com/Foo -

-!! end - -!! test -External image -!! input -External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png -!! result -

External image: Ncwikicol.png -

-!! end - -!! test -External image from https -!! input -External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png -!! result -

External image from https: Ncwikicol.png -

-!! end - -!! test -Link to non-http image, no img tag -!! input -Link to non-http image, no img tag: ftp://example.com/test.jpg -!! result -

Link to non-http image, no img tag: ftp://example.com/test.jpg -

-!! end - -!! test -External links: terminating separator -!! input -Terminating separator: http://example.com/thing, -!! result -

Terminating separator: http://example.com/thing, -

-!! end - -!! test -External links: intervening separator -!! input -Intervening separator: http://example.com/1,2,3 -!! result -

Intervening separator: http://example.com/1,2,3 -

-!! end - -!! test -External links: old bug with URL in query -!! input -Old bug with URL in query: [http://example.com/thing?url=http://example.com link] -!! result -

Old bug with URL in query: link -

-!! end - -!! test -External links: old URL-in-URL bug, mixed protocols -!! input -And again with mixed protocols: [ftp://example.com?url=http://example.com link] -!! result -

And again with mixed protocols: link -

-!!end - -!! test -External links: URL in text -!! input -URL in text: [http://example.com http://example.com] -!! result -

URL in text: http://example.com -

-!! end - -!! test -External links: Clickable images -!! input -ja-style clickable images: [http://example.com http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png] -!! result -

ja-style clickable images: Ncwikicol.png -

-!!end - -!! test -External links: raw ampersand -!! input -Old & use: http://x&y -!! result -

Old & use: http://x&y -

-!! end - -!! test -External links: encoded ampersand -!! input -Old & use: http://x&y -!! result -

Old & use: http://x&y -

-!! end - -!! test -External links: encoded equals (bug 6102) -!! input -http://example.com/?foo=bar -!! result -

http://example.com/?foo=bar -

-!! end - -!! test -External links: [raw ampersand] -!! input -Old & use: [http://x&y] -!! result -

Old & use: [1] -

-!! end - -!! test -External links: [encoded ampersand] -!! input -Old & use: [http://x&y] -!! result -

Old & use: [1] -

-!! end - -!! test -External links: [encoded equals] (bug 6102) -!! input -[http://example.com/?foo=bar] -!! result -

[1] -

-!! end - -!! test -External links: [IDN ignored character reference in hostname; strip it right off] -!! input -[http://e‌xample.com/] -!! result -

[1] -

-!! end - -# FIXME: This test (the IDN characters in the text of a link) is an inconsistency. -# Where an external link could easily circumvent the sanitization of the text of -# a link like this (where an IDN-ignore character is in the URL somewhere), this -# test demands a higher standard. That's a bit strange. -# -# Example: -# -# http://e‌xample.com -> [http://example.com|http://example.com] -# [http://example.com|http://e‌xample.com] -> [http://example.com|http://e‌xample.com] -# -# The first example is sanitized, but the second is not. Any security benefits -# from this production are trivial to circumvent. Either remove this test and -# let the parser(s) do their thing unaccosted, or fix the inconsistency and change -# the test accordingly. -# -# All our love, -# The Parsoid team. -!! test -External links: IDN ignored character reference in hostname; strip it right off -!! input -http://e‌xample.com/ -!! result -

http://example.com/ -

-!! end - -!! test -External links: www.jpeg.org (bug 554) -!! input -http://www.jpeg.org -!!result -

http://www.jpeg.org -

-!! end - -!! test -External links: URL within URL (original bug 2) -!! input -[http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp] -!! result -

[1] -

-!! end - -!! test -BUG 361: URL inside bracketed URL -!! input -[http://www.example.com/foo http://www.example.com/bar] -!! result -

http://www.example.com/bar -

-!! end - -!! test -BUG 361: URL within URL, not bracketed -!! input -http://www.example.com/foo?=http://www.example.com/bar -!! result -

http://www.example.com/foo?=http://www.example.com/bar -

-!! end - -!! test -BUG 289: ">"-token in URL-tail -!! input -http://www.example.com/ -!! result -

http://www.example.com/<hello> -

-!!end - -!! test -BUG 289: literal ">"-token in URL-tail -!! input -http://www.example.com/html -!! result -

http://www.example.com/html -

-!!end - -!! test -BUG 289: ">"-token in bracketed URL -!! input -[http://www.example.com/ stuff] -!! result -

<hello> stuff -

-!!end - -!! test -BUG 289: literal ">"-token in bracketed URL -!! input -[http://www.example.com/html stuff] -!! result -

html stuff -

-!!end - -!! test -BUG 289: literal double quote at end of URL -!! input -http://www.example.com/"hello" -!! result -

http://www.example.com/"hello" -

-!!end - -!! test -BUG 289: literal double quote in bracketed URL -!! input -[http://www.example.com/"hello" stuff] -!! result -

"hello" stuff -

-!!end - -!! test -External links: multiple legal whitespace is fine, Magnus. Don't break it please. (bug 5081) -!! input -[http://www.example.com test] -!! result -

test -

-!! end - -!! test -External links: wiki links within external link (Bug 3695) -!! input -[http://example.com [[wikilink]] embedded in ext link] -!! result -

wikilink embedded in ext link -

-!! end - -!! test -BUG 787: Links with one slash after the url protocol are invalid -!! input -http:/example.com - -[http:/example.com title] -!! result -

http:/example.com -

[http:/example.com title] -

-!! end - -!! test -Bug 2702: Mismatched , and tags are invalid -!! input -''[http://example.com text''] -[http://example.com '''text]''' -''Something [http://example.com in italic''] -''Something [http://example.com mixed''''', even bold]''' -'''''Now [http://example.com both'''''] -!! result -

text -text -Something in italic -Something mixed, even bold -Now both -

-!! end - - -!! test -Bug 4781: %26 in URL -!! input -http://www.example.com/?title=AT%26T -!! result -

http://www.example.com/?title=AT%26T -

-!! end - -# According to http://dev.w3.org/html5/spec/Overview.html#parsing-urls a plain -# % is actually legal in HTML5. Any change in output would need testing though. -!! test -Bug 4781, 5267: %25 in URL -!! input -http://www.example.com/?title=100%25_Bran -!! result -

http://www.example.com/?title=100%25_Bran -

-!! end - -!! test -Bug 4781, 5267: %28, %29 in URL -!! input -http://www.example.com/?title=Ben-Hur_%281959_film%29 -!! result -

http://www.example.com/?title=Ben-Hur_%281959_film%29 -

-!! end - - -!! test -Bug 4781: %26 in autonumber URL -!! input -[http://www.example.com/?title=AT%26T] -!! result -

[1] -

-!! end - -!! test -Bug 4781, 5267: %26 in autonumber URL -!! input -[http://www.example.com/?title=100%25_Bran] -!! result -

[1] -

-!! end - -!! test -Bug 4781, 5267: %28, %29 in autonumber URL -!! input -[http://www.example.com/?title=Ben-Hur_%281959_film%29] -!! result -

[1] -

-!! end - - -!! test -Bug 4781: %26 in bracketed URL -!! input -[http://www.example.com/?title=AT%26T link] -!! result -

link -

-!! end - -!! test -Bug 4781, 5267: %26 in bracketed URL -!! input -[http://www.example.com/?title=100%25_Bran link] -!! result -

link -

-!! end - -!! test -Bug 4781, 5267: %28, %29 in bracketed URL -!! input -[http://www.example.com/?title=Ben-Hur_%281959_film%29 link] -!! result -

link -

-!! end - -!! test -External link containing double-single-quotes in text '' (bug 4598 sanity check) -!! input -Some [http://example.com/ pretty ''italics'' and stuff]! -!! result -

Some pretty italics and stuff! -

-!! end - -!! test -External link containing double-single-quotes in text embedded in italics (bug 4598 sanity check) -!! input -''Some [http://example.com/ pretty ''italics'' and stuff]!'' -!! result -

Some pretty italics and stuff! -

-!! end - -!! test -External link containing double-single-quotes with no space separating the url from text in italics -!! input -[http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm''La muerte de Casagemas'' (1901) en el sitio de [[Museo Picasso (París)|Museo Picasso]].] -!! result -

La muerte de Casagemas (1901) en el sitio de Museo Picasso. -

-!! end - -!! test -URL-encoding in URL functions (single parameter) -!! input -{{localurl:Some page|amp=&}} -!! result -

/index.php?title=Some_page&amp=& -

-!! end - -!! test -URL-encoding in URL functions (multiple parameters) -!! input -{{localurl:Some page|q=?&=&}} -!! result -

/index.php?title=Some_page&q=?&amp=& -

-!! end - -!! test -Brackets in urls -!! input -http://example.com/index.php?foozoid%5B%5D=bar - -http://example.com/index.php?foozoid[]=bar -!! result -

http://example.com/index.php?foozoid%5B%5D=bar -

http://example.com/index.php?foozoid%5B%5D=bar -

-!! end - -!! test -IPv6 urls (bug 21261) -!! options -disabled -!! input -http://[2404:130:0:1000::187:2]/index.php -!! result -

http://[2404:130:0:1000::187:2]/index.php -

-!! end - -### -### Quotes -### - -!! test -Quotes -!! input -Normal text. '''Bold text.''' Normal text. ''Italic text.'' - -Normal text. '''''Bold italic text.''''' Normal text. -!!result -

Normal text. Bold text. Normal text. Italic text. -

Normal text. Bold italic text. Normal text. -

-!! end - - -!! test -Unclosed and unmatched quotes -!! input -'''''Bold italic text '''with bold deactivated''' in between.''''' - -'''''Bold italic text ''with italic deactivated'' in between.''''' - -'''Bold text.. - -..spanning two paragraphs (should not work).''' - -'''Bold tag left open - -''Italic tag left open - -Normal text. - - -'''This year''''s election ''should'' beat '''last year''''s. - -''Tom'''s car is bigger than ''Susan'''s. - -Plain ''italic'''s plain -!! result -

Bold italic text with bold deactivated in between. -

Bold italic text with italic deactivated in between. -

Bold text.. -

..spanning two paragraphs (should not work). -

Bold tag left open -

Italic tag left open -

Normal text. -

This year's election should beat last year's. -

Toms car is bigger than Susans. -

Plain italic's plain -

-!! end - -### -### Tables -### -### some content taken from http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide:_Using_tables -### - -# This should not produce
as
-# is the bare minimun required by the spec, see: -# http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables -!! test -A table with no data. -!! input -{||} -!! result -!! end - -# A table with nothing but a caption is invalid XHTML, we might want to render -# this as

caption

-!! test -A table with nothing but a caption -!! input -{| -|+ caption -|} -!! result - -
caption -
- -!! end - -!! test -Simple table -!! input -{| -| 1 || 2 -|- -| 3 || 4 -|} -!! result - - - - - - -
1 2 -
3 4 -
- -!! end - -!! test -Multiplication table -!! input -{| border="1" cellpadding="2" -|+Multiplication table -|- -! × !! 1 !! 2 !! 3 -|- -! 1 -| 1 || 2 || 3 -|- -! 2 -| 2 || 4 || 6 -|- -! 3 -| 3 || 6 || 9 -|- -! 4 -| 4 || 8 || 12 -|- -! 5 -| 5 || 10 || 15 -|} -!! result - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Multiplication table -
× 1 2 3 -
1 - 1 2 3 -
2 - 2 4 6 -
3 - 3 6 9 -
4 - 4 8 12 -
5 - 5 10 15 -
- -!! end - -!! test -Table rowspan -!! input -{| border=1 -| Cell 1, row 1 -|rowspan=2| Cell 2, row 1 (and 2) -| Cell 3, row 1 -|- -| Cell 1, row 2 -| Cell 3, row 2 -|} -!! result - - - - - - - -
Cell 1, row 1 - Cell 2, row 1 (and 2) - Cell 3, row 1 -
Cell 1, row 2 - Cell 3, row 2 -
- -!! end - -!! test -Nested table -!! input -{| border=1 -| α -| -{| bgcolor=#ABCDEF border=2 -|nested -|- -|table -|} -|the original table again -|} -!! result - - - - -
α - - - - - -
nested -
table -
-
the original table again -
- -!! end - -!! test -Invalid attributes in table cell (bug 1830) -!! input -{| -|Cell:|broken -|} -!! result - - -
broken -
- -!! end - - -!! test -Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html) -!! input -{| -| |[ftp://|x||]" onmouseover="alert(document.cookie)">test -!! result - - - - - -
[ftp://%7Cx]" onmouseover="alert(document.cookie)">test -
- -!! end - - -!! test -Indented table markup mixed with indented pre content (proposed in bug 6200) -!! input - - - - -
- Text that should be rendered preformatted -
-!! result - - - - -
-
Text that should be rendered preformatted
-
-
- -!! end - - -### -### Internal links -### -!! test -Plain link, capitalized -!! input -[[Main Page]] -!! result -

Main Page -

-!! end - -!! test -Plain link, uncapitalized -!! input -[[main Page]] -!! result -

main Page -

-!! end - -!! test -Piped link -!! input -[[Main Page|The Main Page]] -!! result -

The Main Page -

-!! end - -!! test -Broken link -!! input -[[Zigzagzogzagzig]] -!! result -

Zigzagzogzagzig -

-!! end - -!! test -Broken link with fragment -!! input -[[Zigzagzogzagzig#zug]] -!! result -

Zigzagzogzagzig#zug -

-!! end - -!! test -Special page link with fragment -!! input -[[Special:Version#anchor]] -!! result -

Special:Version#anchor -

-!! end - -!! test -Nonexistent special page link with fragment -!! input -[[Special:ThisNameWillHopefullyNeverBeUsed#anchor]] -!! result -

Special:ThisNameWillHopefullyNeverBeUsed#anchor -

-!! end - -!! test -Link with prefix -!! input -xxx[[main Page]], xxx[[Main Page]], Xxx[[main Page]] XXX[[main Page]], XXX[[Main Page]] -!! result -

xxxmain Page, xxxMain Page, Xxxmain Page XXXmain Page, XXXMain Page -

-!! end - -!! test -Link with suffix -!! input -[[Main Page]]xxx, [[Main Page]]XXX, [[Main Page]]!!! -!! result -

Main Pagexxx, Main PageXXX, Main Page!!! -

-!! end - -!! test -Link with 3 brackets -!! input -[[[main page]]] -!! result -

[[[main page]]] -

-!! end - -!! test -Piped link with 3 brackets -!! input -[[[main page|the main page]]] -!! result -

[[[main page|the main page]]] -

-!! end - -!! test -Link with multiple pipes -!! input -[[Main Page|The|Main|Page]] -!! result -

The|Main|Page -

-!! end - -!! test -Link to namespaces -!! input -[[Talk:Parser testing]], [[Meta:Disclaimers]] -!! result -

Talk:Parser testing, Meta:Disclaimers -

-!! end - -!! test -Piped link to namespace -!! input -[[Meta:Disclaimers|The disclaimers]] -!! result -

The disclaimers -

-!! end - -!! test -Link containing } -!! input -[[Usually caused by a typo (oops}]] -!! result -

[[Usually caused by a typo (oops}]] -

-!! end - -!! test -Link containing % (not as a hex sequence) -!! input -[[7% Solution]] -!! result -

7% Solution -

-!! end - -!! test -Link containing % as a single hex sequence interpreted to char -!! input -[[7%25 Solution]] -!! result -

7% Solution -

-!!end - -!! test -Link containing % as a double hex sequence interpreted to hex sequence -!! input -[[7%2525 Solution]] -!! result -

[[7%2525 Solution]] -

-!!end - -!! test -Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors -Example for such a section: == < == -!! input -[[%23%3c]][[%23%3e]] -!! result -

#<#> -

-!! end - -!! test -Link containing "<#" and ">#" as a hex sequences -!! input -[[%3c%23]][[%3e%23]] -!! result -

[[%3c%23]][[%3e%23]] -

-!! end - -!! test -Link containing double-single-quotes '' (bug 4598) -!! input -[[Lista d''e paise d''o munno]] -!! result -

Lista d''e paise d''o munno -

-!! end - -!! test -Link containing double-single-quotes '' in text (bug 4598 sanity check) -!! input -Some [[Link|pretty ''italics'' and stuff]]! -!! result -

Some pretty italics and stuff! -

-!! end - -!! test -Link containing double-single-quotes '' in text embedded in italics (bug 4598 sanity check) -!! input -''Some [[Link|pretty ''italics'' and stuff]]! -!! result -

Some pretty italics and stuff! -

-!! end - -!! test -Link with double quotes in title part (literal) and alternate part (interpreted) -!! input -[[File:Denys Savchenko ''Pentecoste''.jpg]] - -[[''Pentecoste'']] - -[[''Pentecoste''|Pentecoste]] - -[[''Pentecoste''|''Pentecoste'']] -!! result -

File:Denys Savchenko Pentecoste.jpg -

''Pentecoste'' -

Pentecoste -

Pentecoste -

-!! end - -!! test -Broken image links with HTML captions (bug 39700) -!! input -[[File:Nonexistent|]] -[[File:Nonexistent|100px|]] -[[File:Nonexistent|<]] -[[File:Nonexistent|abc]] -!! result -

<script></script> -<script></script> -< -abc -

-!! end - -!! test -Plain link to URL -!! input -[[http://www.example.com]] -!! result -

[[1]] -

-!! end - -!! test -Plain link to URL with link text -!! input -[[http://www.example.com Link text]] -!! result -

[Link text] -

-!! end - -!! test -Plain link to protocol-relative URL -!! input -[[//www.example.com]] -!! result -

[[1]] -

-!! end - -!! test -Plain link to protocol-relative URL with link text -!! input -[[//www.example.com Link text]] -!! result -

[Link text] -

-!! end - - -# I'm fairly sure the expected result here is wrong. -# We want these to be URL links, not pseudo-pages with URLs for titles.... -# However the current output is also pretty screwy. -# -# ---- -# I'm changing it to match the current output--it arguably makes more -# sense in the light of the test above. Old expected result was: -#

Piped link to URL: an example URL -#

-# But I think this test is bordering on "garbage in, garbage out" anyway. -# -- wtm -!! test -Piped link to URL -!! input -Piped link to URL: [[http://www.example.com|an example URL]] -!! result -

Piped link to URL: [example URL] -

-!! end - -!! test -BUG 2: [[page|http://url/]] should link to page, not http://url/ -!! input -[[Main Page|http://url/]] -!! result -

http://url/ -

-!! end - -!! test -BUG 337: Escaped self-links should be bold -!! options -title=[[Bug462]] -!! input -[[Bug462]] [[Bug462]] -!! result -

Bug462 Bug462 -

-!! end - -!! test -Self-link to section should not be bold -!! options -title=[[Main Page]] -!! input -[[Main Page#section]] -!! result -

Main Page#section -

-!! end - -!! article -00 -!! text -This is 00. -!! endarticle - -!!test -Self-link to numeric title -!!options -title=[[0]] -!!input -[[0]] -!!result -

0 -

-!!end - -!!test -Link to numeric-equivalent title -!!options -title=[[0]] -!!input -[[00]] -!!result -

00 -

-!!end - -!! test - inside a link -!! input -[[Main Page]] [[Main Page|the main page [it's not very good]]] -!! result -

[[Main Page]] the main page [it's not very good] -

-!! end - -!! test -Non-breaking spaces in title -!! input -[[  Main   Page  ]] -!! result -

  Main   Page   -

-!!end - -!! test -Internal link with ca linktrail, surrounded by bold apostrophes (bug 27473 primary issue) -!! options -language=ca -!! input -'''[[Main Page]]''' -!! result -

Main Page -

-!! end - -!! test -Internal link with ca linktrail, surrounded by italic apostrophes (bug 27473 primary issue) -!! options -language=ca -!! input -''[[Main Page]]'' -!! result -

Main Page -

-!! end - -!! test -Internal link with en linktrail: no apostrophes (bug 27473) -!! options -language=en -!! input -[[Something]]'nice -!! result -

Something'nice -

-!! end - -!! test -Internal link with ca linktrail with apostrophes (bug 27473) -!! options -language=ca -!! input -[[Something]]'nice -!! result -

Something'nice -

-!! end - -!! test -Internal link with kaa linktrail with apostrophes (bug 27473) -!! options -language=kaa -!! input -[[Something]]'nice -!! result -

Something'nice -

-!! end - -### -### Interwiki links (see maintenance/interwiki.sql) -### - -!! test -Inline interwiki link -!! input -[[MeatBall:SoftSecurity]] -!! result -

MeatBall:SoftSecurity -

-!! end - -!! test -Inline interwiki link with empty title (bug 2372) -!! input -[[MeatBall:]] -!! result -

MeatBall: -

-!! end - -!! test -Interwiki link encoding conversion (bug 1636) -!! input -*[[Wikipedia:ro:Olteniţa]] -*[[Wikipedia:ro:Olteniţa]] -!! result - - -!! end - -!! test -Interwiki link with fragment (bug 2130) -!! input -[[MeatBall:SoftSecurity#foo]] -!! result -

MeatBall:SoftSecurity#foo -

-!! end - -!! test -Interlanguage link -!! input -Blah blah blah -[[zh:Chinese]] -!!result -

Blah blah blah -

-!! end - -!! test -Double interlanguage link -!! input -Blah blah blah -[[es:Spanish]] -[[zh:Chinese]] -!!result -

Blah blah blah -

-!! end - -!! test -Interlanguage link, with prefix links -!! options -language=ln -!! input -Blah blah blah -[[zh:Chinese]] -!!result -

Blah blah blah -

-!! end - -!! test -Double interlanguage link, with prefix links (bug 8897) -!! options -language=ln -!! input -Blah blah blah -[[es:Spanish]] -[[zh:Chinese]] -!!result -

Blah blah blah -

-!! end - - -## -## XHTML tidiness -### - -!! test -
to
-!! input -1
2
3 -!! result -

1
2
3 -

-!! end - -!! test -Incorrecly removing closing slashes from correctly formed XHTML -!! input -
-!! result -


-

-!! end - -!! test -Failing to transform badly formed HTML into correct XHTML -!! input -
-
-
-!! result -


-
-
-

-!!end - -!! test -Horizontal ruler (should it add that extra space?) -!! input -
-
-foo
bar -!! result -
-
-foo
bar - -!! end - -!! test -Horizontal ruler -- 4+ dashes render hr -!! input ----- -!! result -
- -!! end - -!! test -Horizontal ruler -- eats additional dashes on the same line -!! input ---------- -!! result -
- -!! end - -!! test -Horizontal ruler -- does not collaps dashes on consecutive lines -!! input ----- ----- -!! result -
-
- -!! end - -!! test -Horizontal ruler -- <4 dashes render as plain text -!! input ---- -!! result -

--- -

-!! end - -### -### Block-level elements -### -!! test -Common list -!! input -*Common list -* item 2 -*item 3 -!! result -
  • Common list -
  • item 2 -
  • item 3 -
- -!! end - -!! test -Numbered list -!! input -#Numbered list -#item 2 -# item 3 -!! result -
  1. Numbered list -
  2. item 2 -
  3. item 3 -
- -!! end - -!! test -Mixed list -!! input -*Mixed list -*# with numbers -** and bullets -*# and numbers -*bullets again -**bullet level 2 -***bullet level 3 -***#Number on level 4 -**bullet level 2 -**#Number on level 3 -**#Number on level 3 -*#number level 2 -*Level 1 -*** Level 3 -#** Level 3, but ordered -!! result -
  • Mixed list -
    1. with numbers -
    -
    • and bullets -
    -
    1. and numbers -
    -
  • bullets again -
    • bullet level 2 -
      • bullet level 3 -
        1. Number on level 4 -
        -
      -
    • bullet level 2 -
      1. Number on level 3 -
      2. Number on level 3 -
      -
    -
    1. number level 2 -
    -
  • Level 1 -
      • Level 3 -
      -
    -
-
      • Level 3, but ordered -
      -
    -
- -!! end - -!! test -Nested lists 1 -!! input -*foo -**bar -!! result -
  • foo -
    • bar -
    -
- -!! end - -!! test -Nested lists 2 -!! input -**foo -*bar -!! result -
    • foo -
    -
  • bar -
- -!! end - -!! test -Nested lists 3 (first element empty) -!! input -* -**bar -!! result -
  • -
    • bar -
    -
- -!! end - -!! test -Nested lists 4 (first element empty) -!! input -** -*bar -!! result -
    • -
    -
  • bar -
- -!! end - -!! test -Nested lists 5 (both elements empty) -!! input -** -* -!! result -
    • -
    -
  • -
- -!! end - -!! test -Nested lists 6 (both elements empty) -!! input -* -** -!! result -
  • -
    • -
    -
- -!! end - -!! test -Nested lists 7 (skip initial nesting levels) -!! input -*** foo -!! result -
      • foo -
      -
    -
- -!! end - -!! test -Nested lists 8 (multiple nesting transitions) -!! input -* foo -*** bar -** baz -* boo -!! result -
  • foo -
      • bar -
      -
    • baz -
    -
  • boo -
- -!! end - - -!! test -List items are not parsed correctly following a
 block (bug 785)
-!! input
-* 
foo
-*
bar
-* zar -!! result -
  • foo
    -
  • bar
    -
  • zar -
- -!! end - -!! test -List items from template -!! input - -{{inner list}} -* item 2 - -* item 0 -{{inner list}} -* item 2 - -* item 0 -* notSOL{{inner list}} -* item 2 -!! result -
  • item 1 -
  • item 2 -
-
  • item 0 -
  • item 1 -
  • item 2 -
-
  • item 0 -
  • notSOL -
  • item 1 -
  • item 2 -
- -!! end - -!! test -List interrupted by empty line or heading -!! input -* foo - -** bar -== A heading == -* Another list item -!! result -
  • foo -
-
    • bar -
    -
-

[edit] A heading

-
  • Another list item -
- -!!end - - -### -### Magic Words -### - -!! test -Magic Word: {{CURRENTDAY}} -!! input -{{CURRENTDAY}} -!! result -

1 -

-!! end - -!! test -Magic Word: {{CURRENTDAY2}} -!! input -{{CURRENTDAY2}} -!! result -

01 -

-!! end - -!! test -Magic Word: {{CURRENTDAYNAME}} -!! input -{{CURRENTDAYNAME}} -!! result -

Thursday -

-!! end - -!! test -Magic Word: {{CURRENTDOW}} -!! input -{{CURRENTDOW}} -!! result -

4 -

-!! end - -!! test -Magic Word: {{CURRENTMONTH}} -!! input -{{CURRENTMONTH}} -!! result -

01 -

-!! end - -!! test -Magic Word: {{CURRENTMONTHABBREV}} -!! input -{{CURRENTMONTHABBREV}} -!! result -

Jan -

-!! end - -!! test -Magic Word: {{CURRENTMONTHNAME}} -!! input -{{CURRENTMONTHNAME}} -!! result -

January -

-!! end - -!! test -Magic Word: {{CURRENTMONTHNAMEGEN}} -!! input -{{CURRENTMONTHNAMEGEN}} -!! result -

January -

-!! end - -!! test -Magic Word: {{CURRENTTIME}} -!! input -{{CURRENTTIME}} -!! result -

00:02 -

-!! end - -!! test -Magic Word: {{CURRENTWEEK}} (@bug 4594) -!! input -{{CURRENTWEEK}} -!! result -

1 -

-!! end - -!! test -Magic Word: {{CURRENTYEAR}} -!! input -{{CURRENTYEAR}} -!! result -

1970 -

-!! end - -!! test -Magic Word: {{FULLPAGENAME}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{FULLPAGENAME}} -!! result -

User:Ævar Arnfjörð Bjarmason -

-!! end - -!! test -Magic Word: {{FULLPAGENAMEE}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{FULLPAGENAMEE}} -!! result -

User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason -

-!! end - -!! test -Magic Word: {{NAMESPACE}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{NAMESPACE}} -!! result -

User -

-!! end - -!! test -Magic Word: {{NAMESPACEE}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{NAMESPACEE}} -!! result -

User -

-!! end - -!! test -Magic Word: {{NAMESPACENUMBER}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{NAMESPACENUMBER}} -!! result -

2 -

-!! end - -!! test -Magic Word: {{NUMBEROFFILES}} -!! input -{{NUMBEROFFILES}} -!! result -

2 -

-!! end - -!! test -Magic Word: {{PAGENAME}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{PAGENAME}} -!! result -

Ævar Arnfjörð Bjarmason -

-!! end - -!! test -Magic Word: {{PAGENAME}} with metacharacters -!! options -title=[['foo & bar = baz']] -!! input -''{{PAGENAME}}'' -!! result -

'foo & bar = baz' -

-!! end - -!! test -Magic Word: {{PAGENAME}} with metacharacters (bug 26781) -!! options -title=[[*RFC 1234 http://example.com/]] -!! input -{{PAGENAME}} -!! result -

*RFC 1234 http://example.com/ -

-!! end - -!! test -Magic Word: {{PAGENAMEE}} -!! options -title=[[User:Ævar Arnfjörð Bjarmason]] -!! input -{{PAGENAMEE}} -!! result -

%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason -

-!! end - -!! test -Magic Word: {{PAGENAMEE}} with metacharacters (bug 26781) -!! options -title=[[*RFC 1234 http://example.com/]] -!! input -{{PAGENAMEE}} -!! result -

*RFC_1234_http://example.com/ -

-!! end - -!! test -Magic Word: {{REVISIONID}} -!! input -{{REVISIONID}} -!! result -

1337 -

-!! end - -!! test -Magic Word: {{SCRIPTPATH}} -!! input -{{SCRIPTPATH}} -!! result -

/ -

-!! end - -!! test -Magic Word: {{SERVER}} -!! input -{{SERVER}} -!! result -

http://Britney-Spears -

-!! end - -!! test -Magic Word: {{SERVERNAME}} -!! input -{{SERVERNAME}} -!! result -

Britney-Spears -

-!! end - -!! test -Magic Word: {{SITENAME}} -!! input -{{SITENAME}} -!! result -

MediaWiki -

-!! end - -!! test -Namespace 1 {{ns:1}} -!! input -{{ns:1}} -!! result -

Talk -

-!! end - -!! test -Namespace 1 {{ns:01}} -!! input -{{ns:01}} -!! result -

Talk -

-!! end - -!! test -Namespace 0 {{ns:0}} (bug 4783) -!! input -{{ns:0}} -!! result - -!! end - -!! test -Namespace 0 {{ns:00}} (bug 4783) -!! input -{{ns:00}} -!! result - -!! end - -!! test -Namespace -1 {{ns:-1}} -!! input -{{ns:-1}} -!! result -

Special -

-!! end - -!! test -Namespace User {{ns:User}} -!! input -{{ns:User}} -!! result -

User -

-!! end - -!! test -Namespace User talk {{ns:User_talk}} -!! input -{{ns:User_talk}} -!! result -

User talk -

-!! end - -!! test -Namespace User talk {{ns:uSeR tAlK}} -!! input -{{ns:uSeR tAlK}} -!! result -

User talk -

-!! end - -!! test -Namespace File {{ns:File}} -!! input -{{ns:File}} -!! result -

File -

-!! end - -!! test -Namespace File {{ns:Image}} -!! input -{{ns:Image}} -!! result -

File -

-!! end - -!! test -Namespace (lang=de) Benutzer {{ns:User}} -!! options -language=de -!! input -{{ns:User}} -!! result -

Benutzer -

-!! end - -!! test -Namespace (lang=de) Benutzer Diskussion {{ns:3}} -!! options -language=de -!! input -{{ns:3}} -!! result -

Benutzer Diskussion -

-!! end - - -!! test -Urlencode -!! input -{{urlencode:hi world?!}} -{{urlencode:hi world?!|WIKI}} -{{urlencode:hi world?!|PATH}} -{{urlencode:hi world?!|QUERY}} -!! result -

hi+world%3F%21 -hi_world%3F! -hi%20world%3F%21 -hi+world%3F%21 -

-!! end - -### -### Magic links -### -!! test -Magic links: internal link to RFC (bug 479) -!! input -[[RFC 123]] -!! result -

RFC 123 -

-!! end - -!! test -Magic links: RFC (bug 479) -!! input -RFC 822 -!! result -

RFC 822 -

-!! end - -!! test -Magic links: ISBN (bug 1937) -!! input -ISBN 0-306-40615-2 -!! result -

ISBN 0-306-40615-2 -

-!! end - -!! test -Magic links: PMID incorrectly converts space to underscore -!! input -PMID 1234 -!! result -

PMID 1234 -

-!! end - -### -### Templates -#### - -!! test -Nonexistent template -!! input -{{thistemplatedoesnotexist}} -!! result -

Template:Thistemplatedoesnotexist -

-!! end - -!! article -Template:test -!! text -This is a test template -!! endarticle - -!! test -Simple template -!! input -{{test}} -!! result -

This is a test template -

-!! end - -!! test -Template with explicit namespace -!! input -{{Template:test}} -!! result -

This is a test template -

-!! end - - -!! article -Template:paramtest -!! text -This is a test template with parameter {{{param}}} -!! endarticle - -!! test -Template parameter -!! input -{{paramtest|param=foo}} -!! result -

This is a test template with parameter foo -

-!! end - -!! article -Template:paramtestnum -!! text -[[{{{1}}}|{{{2}}}]] -!! endarticle - -!! test -Template unnamed parameter -!! input -{{paramtestnum|Main Page|the main page}} -!! result -

the main page -

-!! end - -!! article -Template:templatesimple -!! text -(test) -!! endarticle - -!! article -Template:templateredirect -!! text -#redirect [[Template:templatesimple]] -!! endarticle - -!! article -Template:templateasargtestnum -!! text -{{{{{1}}}}} -!! endarticle - -!! article -Template:templateasargtest -!! text -{{template{{{templ}}}}} -!! endarticle - -!! article -Template:templateasargtest2 -!! text -{{{{{templ}}}}} -!! endarticle - -!! test -Template with template name as unnamed argument -!! input -{{templateasargtestnum|templatesimple}} -!! result -

(test) -

-!! end - -!! test -Template with template name as argument -!! input -{{templateasargtest|templ=simple}} -!! result -

(test) -

-!! end - -!! test -Template with template name as argument (2) -!! input -{{templateasargtest2|templ=templatesimple}} -!! result -

(test) -

-!! end - -!! article -Template:templateasargtestdefault -!! text -{{{{{templ|templatesimple}}}}} -!! endarticle - -!! article -Template:templa -!! text -'''templ''' -!! endarticle - -!! test -Template with default value -!! input -{{templateasargtestdefault}} -!! result -

(test) -

-!! end - -!! test -Template with default value (value set) -!! input -{{templateasargtestdefault|templ=templa}} -!! result -

templ -

-!! end - -!! test -Template redirect -!! input -{{templateredirect}} -!! result -

(test) -

-!! end - -!! test -Template with argument in separate line -!! input -{{ templateasargtest | - templ = simple }} -!! result -

(test) -

-!! end - -!! test -Template with complex template as argument -!! input -{{paramtest| - param ={{ templateasargtest | - templ = simple }}}} -!! result -

This is a test template with parameter (test) -

-!! end - -!! test -Template with thumb image (with link in description) -!! input -{{paramtest| - param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}} -!! result -This is a test template with parameter - -!! end - -!! article -Template:complextemplate -!! text -{{{1}}} {{paramtest| - param ={{{param}}}}} -!! endarticle - -!! test -Template with complex arguments -!! input -{{complextemplate| - param ={{ templateasargtest | - templ = simple }}|[[Template:complextemplate|link]]}} -!! result -

link This is a test template with parameter (test) -

-!! end - -!! test -BUG 553: link with two variables in a piped link -!! input -{| -|[[{{{1}}}|{{{2}}}]] -|} -!! result - - -
[[{{{1}}}|{{{2}}}]] -
- -!! end - -!! test -Magic variable as template parameter -!! input -{{paramtest|param={{SITENAME}}}} -!! result -

This is a test template with parameter MediaWiki -

-!! end - -!! article -Template:linktest -!! text -[[{{{param}}}|link]] -!! endarticle - -!! test -Template parameter as link source -!! input -{{linktest|param=Main Page}} -!! result -

link -

-!! end - - -!!article -Template:paramtest2 -!! text -including another template, {{paramtest|param={{{arg}}}}} -!! endarticle - -!! test -Template passing argument to another template -!! input -{{paramtest2|arg='hmm'}} -!! result -

including another template, This is a test template with parameter 'hmm' -

-!! end - -!! article -Template:Linktest2 -!! text -Main Page -!! endarticle - -!! test -Template as link source -!! input -[[{{linktest2}}]] -!! result -

Main Page -

-!! end - - -!! article -Template:loop1 -!! text -{{loop2}} -!! endarticle - -!! article -Template:loop2 -!! text -{{loop1}} -!! endarticle - -!! test -Template infinite loop -!! input -{{loop1}} -!! result -

Template loop detected: Template:Loop1 -

-!! end - -!! test -Template from main namespace -!! input -{{:Main Page}} -!! result -

blah blah -

-!! end - -!! article -Template:table -!! text -{| -| 1 || 2 -|- -| 3 || 4 -|} -!! endarticle - -!! test -BUG 529: Template with table, not included at beginning of line -!! input -foo {{table}} -!! result -

foo -

- - - - - - -
1 2 -
3 4 -
- -!! end - -!! test -BUG 523: Template shouldn't eat newline (or add an extra one before table) -!! input -foo -{{table}} -!! result -

foo -

- - - - - - -
1 2 -
3 4 -
- -!! end - -!! test -BUG 41: Template parameters shown as broken links -!! input -{{{parameter}}} -!! result -

{{{parameter}}} -

-!! end - - -!! article -Template:MSGNW test -!! text -''None'' of '''this''' should be -* interpreted - but rather passed unmodified -{{test}} -!! endarticle - -# hmm, fix this or just deprecate msgnw and document its behavior? -!! test -msgnw keyword -!! options -disabled -!! input -{{msgnw:MSGNW test}} -!! result -

''None'' of '''this''' should be -* interpreted - but rather passed unmodified -{{test}} -

-!! end - -!! test -int keyword -!! input -{{int:youhavenewmessages|lots of money|not!}} -!! result -

You have lots of money (not!). -

-!! end - -!! article -Template:Includes -!! text -Foozarbar -!! endarticle - -!! test - and being included -!! input -{{Includes}} -!! result -

Foobar -

-!! end - -!! article -Template:Includes2 -!! text -Foobar -!! endarticle - -!! test - being included -!! input -{{Includes2}} -!! result -

Foo -

-!! end - - -!! article -Template:Includes3 -!! text -Foobarzar -!! endarticle - -!! test - and being included -!! input -{{Includes3}} -!! result -

Foo -

-!! end - -!! test - and on a page -!! input -Foozarbar -!! result -

Foozar -

-!! end - -!! test - on a page -!! input -Foobar -!! result -

Foobar -

-!! end - -!! article -Template:Includeonly section -!! text - -==Includeonly section== - -==Section T-1== -!!endarticle - -!! test -Bug 6563: Edit link generation for section shown by -!! input -{{includeonly section}} -!! result -

[edit] Includeonly section

-

[edit] Section T-1

- -!! end - -# Uses same input as the contents of [[Template:Includeonly section]] -!! test -Bug 6563: Section extraction for section shown by -!! options -section=T-2 -!! input - -==Includeonly section== - -==Section T-2== -!! result -==Section T-2== -!! end - -!! test -Bug 6563: Edit link generation for section suppressed by -!! input - -==Includeonly section== - -==Section 1== -!! result -

[edit] Section 1

- -!! end - -!! test -Bug 6563: Section extraction for section suppressed by -!! options -section=1 -!! input - -==Includeonly section== - -==Section 1== -!! result -==Section 1== -!! end - -### -### Pre-save transform tests -### -!! test -pre-save transform: subst: -!! options -PST -!! input -{{subst:test}} -!! result -This is a test template -!! end - -!! test -pre-save transform: normal template -!! options -PST -!! input -{{test}} -!! result -{{test}} -!! end - -!! test -pre-save transform: nonexistent template -!! options -PST -!! input -{{thistemplatedoesnotexist}} -!! result -{{thistemplatedoesnotexist}} -!! end - - -!! test -pre-save transform: subst magic variables -!! options -PST -!! input -{{subst:SITENAME}} -!! result -MediaWiki -!! end - -# This is bug 89, which I fixed. -- wtm -!! test -pre-save transform: subst: templates with parameters -!! options -pst -!! input -{{subst:paramtest|param="something else"}} -!! result -This is a test template with parameter "something else" -!! end - -!! article -Template:nowikitest -!! text -'''not wiki''' -!! endarticle - -!! test -pre-save transform: nowiki in subst (bug 1188) -!! options -pst -!! input -{{subst:nowikitest}} -!! result -'''not wiki''' -!! end - - -!! article -Template:commenttest -!! text -This template has in it. -!! endarticle - -!! test -pre-save transform: comment in subst (bug 1936) -!! options -pst -!! input -{{subst:commenttest}} -!! result -This template has in it. -!! end - -!! test -pre-save transform: unclosed tag -!! options -pst noxml -!! input -'''not wiki''' -!! result -'''not wiki''' -!! end - -!! test -pre-save transform: mixed tag case -!! options -pst noxml -!! input -'''not wiki''' -!! result -'''not wiki''' -!! end - -!! test -pre-save transform: unclosed comment in -!! options -pst noxml -!! input -wikinowiki -!!result - -!!end - -!! test -pre-save transform: comment containing extension -!! options -pst -!! input - -!!result - -!!end - -!! test -pre-save transform: comment containing nowiki -!! options -pst -!! input - -!!result - -!!end - -!! test -pre-save transform: in subst (bug 3298) -!! options -pst -!! input -{{subst:Includes}} -!! result -Foobar -!! end - -!! test -pre-save transform: in subst (bug 3298) -!! options -pst -!! input -{{subst:Includes2}} -!! result -Foo -!! end - -!! article -Template:SubstTest -!!text -{{subst:Includes}} -!! endarticle - -!! article -Template:SafeSubstTest -!! text -{{safesubst:Includes}} -!! endarticle - -!! test -bug 22297: safesubst: works during PST -!! options -pst -!! input -{{subst:SafeSubstTest}}{{safesubst:SubstTest}} -!! result -FoobarFoobar -!! end - -!! test -bug 22297: safesubst: works during normal parse -!! input -{{SafeSubstTest}} -!! result -

Foobar -

-!! end - -!! test: -subst: does not work during normal parse -!! input -{{SubstTest}} -!! result -

{{subst:Includes}} -

-!! end - -!! test -pre-save transform: context links ("pipe trick") -!! options -pst -!! input -[[Article (context)|]] -[[Bar:Article|]] -[[:Bar:Article|]] -[[Bar:Article (context)|]] -[[:Bar:Article (context)|]] -[[|Article]] -[[|Article (context)]] -[[Bar:X (Y) Z|]] -[[:Bar:X (Y) Z|]] -!! result -[[Article (context)|Article]] -[[Bar:Article|Article]] -[[:Bar:Article|Article]] -[[Bar:Article (context)|Article]] -[[:Bar:Article (context)|Article]] -[[Article]] -[[Article (context)]] -[[Bar:X (Y) Z|X (Y) Z]] -[[:Bar:X (Y) Z|X (Y) Z]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with interwiki prefix -!! options -pst -!! input -[[interwiki:Article|]] -[[:interwiki:Article|]] -[[interwiki:Bar:Article|]] -[[:interwiki:Bar:Article|]] -!! result -[[interwiki:Article|Article]] -[[:interwiki:Article|Article]] -[[interwiki:Bar:Article|Bar:Article]] -[[:interwiki:Bar:Article|Bar:Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with parens in title -!! options -pst title=[[Somearticle (context)]] -!! input -[[|Article]] -!! result -[[Article (context)|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with comma in title -!! options -pst title=[[Someplace, Somewhere]] -!! input -[[|Otherplace]] -[[Otherplace, Elsewhere|]] -[[Otherplace, Elsewhere, Anywhere|]] -!! result -[[Otherplace, Somewhere|Otherplace]] -[[Otherplace, Elsewhere|Otherplace]] -[[Otherplace, Elsewhere, Anywhere|Otherplace]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with parens and comma -!! options -pst title=[[Someplace (IGNORED), Somewhere]] -!! input -[[|Otherplace]] -[[Otherplace (place), Elsewhere|]] -!! result -[[Otherplace, Somewhere|Otherplace]] -[[Otherplace (place), Elsewhere|Otherplace]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with comma and parens -!! options -pst title=[[Who, me? (context)]] -!! input -[[|Yes, you.]] -[[Me, Myself, and I (1937 song)|]] -!! result -[[Yes, you. (context)|Yes, you.]] -[[Me, Myself, and I (1937 song)|Me, Myself, and I]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with namespace -!! options -pst title=[[Ns:Somearticle]] -!! input -[[|Article]] -!! result -[[Ns:Article|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with namespace and parens -!! options -pst title=[[Ns:Somearticle (context)]] -!! input -[[|Article]] -!! result -[[Ns:Article (context)|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with namespace and comma -!! options -pst title=[[Ns:Somearticle, Context, Whatever]] -!! input -[[|Article]] -!! result -[[Ns:Article, Context, Whatever|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with namespace, comma and parens -!! options -pst title=[[Ns:Somearticle, Context (context)]] -!! input -[[|Article]] -!! result -[[Ns:Article (context)|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with namespace, parens and comma -!! options -pst title=[[Ns:Somearticle (IGNORED), Context]] -!! input -[[|Article]] -!! result -[[Ns:Article, Context|Article]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with full-width parens and no space (Japanese and Chinese style, bug 30149) -!! options -pst -!! input -[[Article(context)|]] -[[Bar:Article(context)|]] -[[:Bar:Article(context)|]] -[[|Article(context)]] -[[Bar:X(Y)Z|]] -[[:Bar:X(Y)Z|]] -!! result -[[Article(context)|Article]] -[[Bar:Article(context)|Article]] -[[:Bar:Article(context)|Article]] -[[Article(context)]] -[[Bar:X(Y)Z|X(Y)Z]] -[[:Bar:X(Y)Z|X(Y)Z]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with full-width parens and space (Japanese and Chinese style, bug 30149) -!! options -pst -!! input -[[Article (context)|]] -[[Bar:Article (context)|]] -[[:Bar:Article (context)|]] -[[|Article (context)]] -[[Bar:X (Y) Z|]] -[[:Bar:X (Y) Z|]] -!! result -[[Article (context)|Article]] -[[Bar:Article (context)|Article]] -[[:Bar:Article (context)|Article]] -[[Article (context)]] -[[Bar:X (Y) Z|X (Y) Z]] -[[:Bar:X (Y) Z|X (Y) Z]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with parens and no space (Korean style, bug 30149) -!! options -pst -!! input -[[Article(context)|]] -[[Bar:Article(context)|]] -[[:Bar:Article(context)|]] -[[|Article(context)]] -[[Bar:X(Y)Z|]] -[[:Bar:X(Y)Z|]] -!! result -[[Article(context)|Article]] -[[Bar:Article(context)|Article]] -[[:Bar:Article(context)|Article]] -[[Article(context)]] -[[Bar:X(Y)Z|X(Y)Z]] -[[:Bar:X(Y)Z|X(Y)Z]] -!! end - -!! test -pre-save transform: context links ("pipe trick") with commas (bug 21660) -!! options -pst -!! input -[[Article (context), context|]] -[[Article (context),context|]] -[[Bar:Article (context), context|]] -[[Bar:Article (context),context|]] -[[:Bar:Article (context), context|]] -[[:Bar:Article (context),context|]] -!! result -[[Article (context), context|Article]] -[[Article (context),context|Article]] -[[Bar:Article (context), context|Article]] -[[Bar:Article (context),context|Article]] -[[:Bar:Article (context), context|Article]] -[[:Bar:Article (context),context|Article]] -!! end - -!! test -pre-save transform: trim trailing empty lines -!! options -pst -!! input -Empty lines are trimmed - - - - -!! result -Empty lines are trimmed -!! end - -!! test -pre-save transform: Signature expansion -!! options -pst -!! input -* ~~~ -* ~~~ -* ~~~ -* ~~~ -!! result -* [[Special:Contributions/127.0.0.1|127.0.0.1]] -* [[Special:Contributions/127.0.0.1|127.0.0.1]] -* [[Special:Contributions/127.0.0.1|127.0.0.1]] -* [[Special:Contributions/127.0.0.1|127.0.0.1]] -!! end - - -!! test -pre-save transform: Signature expansion in nowiki tags (bug 93) -!! options -pst disabled -!! input -Shall not expand: - -~~~~ - -~~~~ - -~~~~ - -~~~~ - -{{subst:Foo}} shall be converted to FOO - -As well as inside noinclude/onlyinclude -{{subst:Foo}} -{{subst:Foo}} - -But not inside includeonly -{{subst:Foo}} -!! result -Shall not expand: - -~~~~ - -~~~~ - -~~~~ - -~~~~ - -FOO shall be converted to FOO - -As well as inside noinclude/onlyinclude -FOO -FOO - -But not inside includeonly -{{subst:Foo}} -!! end - -### -### Message transform tests -### -!! test -message transform: magic variables -!! options -msg -!! input -{{SITENAME}} -!! result -MediaWiki -!! end - -!! test -message transform: should not transform wiki markup -!! options -msg -!! input -''test'' -!! result -''test'' -!! end - -!! test -message transform: in transcluded template (bug 4926) -!! options -msg -!! input -{{Includes}} -!! result -Foobar -!! end - -!! test -message transform: in transcluded template (bug 4926) -!! options -msg -!! input -{{Includes2}} -!! result -Foo -!! end - -!! test -{{#special:}} page name, known -!! options -msg -!! input -{{#special:Recentchanges}} -!! result -Special:RecentChanges -!! end - -!! test -{{#special:}} page name with subpage, known -!! options -msg -!! input -{{#special:Recentchanges/param}} -!! result -Special:RecentChanges/param -!! end - -!! test -{{#special:}} page name, unknown -!! options -msg -!! input -{{#special:foobarnonexistent}} -!! result -No such special page -!! end - -!! test -{{#speciale:}} page name, known -!! options -msg -!! input -{{#speciale:Recentchanges}} -!! result -Special:RecentChanges -!! end - -!! test -{{#speciale:}} page name with subpage, known -!! options -msg -!! input -{{#speciale:Recentchanges/param}} -!! result -Special:RecentChanges/param -!! end - -!! test -{{#speciale:}} page name, unknown -!! options -msg -!! input -{{#speciale:foobarnonexistent}} -!! result -No_such_special_page -!! end - -### -### Images -### -!! test -Simple image -!! input -[[Image:foobar.jpg]] -!! result -

Foobar.jpg -

-!! end - -!! test -Right-aligned image -!! input -[[Image:foobar.jpg|right]] -!! result -
Foobar.jpg
- -!! end - -!! test -Simple image (using File: namespace, now canonical) -!! input -[[File:foobar.jpg]] -!! result -

Foobar.jpg -

-!! end - -!! test -Image with caption -!! input -[[Image:foobar.jpg|right|Caption text]] -!! result -
Caption text
- -!! end - -!! test -Image with link parameter, wiki target -!! input -[[Image:foobar.jpg|link=Target page]] -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter, URL target -!! input -[[Image:foobar.jpg|link=http://example.com/]] -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter, wgExternalLinkTarget -!! input -[[Image:foobar.jpg|link=http://example.com/]] -!! config -wgExternalLinkTarget='foobar' -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter, wgNoFollowLinks set to false -!! input -[[Image:foobar.jpg|link=http://example.com/]] -!! config -wgNoFollowLinks=false -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter, wgNoFollowDomainExceptions -!! input -[[Image:foobar.jpg|link=http://example.com/]] -!! config -wgNoFollowDomainExceptions='example.com' -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter, wgExternalLinkTarget, unnamed parameter -!! input -[[Image:foobar.jpg|link=http://example.com/|Title]] -!! config -wgExternalLinkTarget='foobar' -!! result -

Title -

-!! end - -!! test -Image with empty link parameter -!! input -[[Image:foobar.jpg|link=]] -!! result -

Foobar.jpg -

-!! end - -!! test -Image with link parameter (wiki target) and unnamed parameter -!! input -[[Image:foobar.jpg|link=Target page|Title]] -!! result -

Title -

-!! end - -!! test -Image with link parameter (URL target) and unnamed parameter -!! input -[[Image:foobar.jpg|link=http://example.com/|Title]] -!! result -

Title -

-!! end - -!! test -Thumbnail image with link parameter -!! input -[[Image:foobar.jpg|thumb|link=http://example.com/|Title]] -!! result -
Title
- -!! end - -!! test -Image with frame and link -!! input -[[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]]] -!! result -
This is a test image Main Page
- -!! end - -!! test -Image with frame and link and explicit alt -!! input -[[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]|alt=Altitude]] -!! result -
Altitude
This is a test image Main Page
- -!! end - -!! test -Image with wiki markup in implicit alt -!! input -[[Image:Foobar.jpg|testing '''bold''' in alt]] -!! result -

testing bold in alt -

-!! end - -!! test -Image with wiki markup in explicit alt -!! input -[[Image:Foobar.jpg|alt=testing '''bold''' in alt]] -!! result -

testing bold in alt -

-!! end - -!! test -Link to image page- image page normally doesn't exists, hence edit link -Add test with existing image page -#

Image:test -!! input -[[:Image:test]] -!! result -

Image:test -

-!! end - -!! test -bug 18784 Link to non-existent image page with caption should use caption as link text -!! input -[[:Image:test|caption]] -!! result -

caption -

-!! end - -!! test -Frameless image caption with a free URL -!! input -[[Image:foobar.jpg|http://example.com]] -!! result -

http://example.com -

-!! end - -!! test -Thumbnail image caption with a free URL -!! input -[[Image:foobar.jpg|thumb|http://example.com]] -!! result - - -!! end - -!! test -Thumbnail image caption with a free URL and explicit alt -!! input -[[Image:foobar.jpg|thumb|http://example.com|alt=Alteration]] -!! result - - -!! end - -!! test -BUG 1887: A ISBN with a thumbnail -!! input -[[Image:foobar.jpg|thumb|ISBN 1235467890]] -!! result - - -!! end - -!! test -BUG 1887: A RFC with a thumbnail -!! input -[[Image:foobar.jpg|thumb|This is RFC 12354]] -!! result -
This is RFC 12354
- -!! end - -!! test -BUG 1887: A mailto link with a thumbnail -!! input -[[Image:foobar.jpg|thumb|Please mailto:nobody@example.com]] -!! result - - -!! end - -# Pending resolution to bug 368 -!! test -BUG 648: Frameless image caption with a link -!! input -[[Image:foobar.jpg|text with a [[link]] in it]] -!! result -

text with a link in it -

-!! end - -!! test -BUG 648: Frameless image caption with a link (suffix) -!! input -[[Image:foobar.jpg|text with a [[link]]foo in it]] -!! result -

text with a linkfoo in it -

-!! end - -!! test -BUG 648: Frameless image caption with an interwiki link -!! input -[[Image:foobar.jpg|text with a [[MeatBall:Link]] in it]] -!! result -

text with a MeatBall:Link in it -

-!! end - -!! test -BUG 648: Frameless image caption with a piped interwiki link -!! input -[[Image:foobar.jpg|text with a [[MeatBall:Link|link]] in it]] -!! result -

text with a link in it -

-!! end - -!! test -Escape HTML special chars in image alt text -!! input -[[Image:foobar.jpg|& < > "]] -!! result -

& < > " -

-!! end - -!! test -BUG 499: Alt text should have Ӓ, not &1234; -!! input -[[Image:foobar.jpg|♀]] -!! result -

♀ -

-!! end - -!! test -Broken image caption with link -!! input -[[Image:Foobar.jpg|thumb|This is a broken caption. But [[Main Page|this]] is just an ordinary link. -!! result -

[[Image:Foobar.jpg|thumb|This is a broken caption. But this is just an ordinary link. -

-!! end - -!! test -Image caption containing another image -!! input -[[Image:Foobar.jpg|thumb|This is a caption with another [[Image:icon.png|image]] inside it!]] -!! result -
This is a caption with another image inside it!
- -!! end - -!! test -Image caption containing a newline -!! input -[[Image:Foobar.jpg|This -*is some text]] -!! result -

This *is some text -

-!!end - - -!! test -Bug 3090: External links other than http: in image captions -!! input -[[Image:Foobar.jpg|thumb|200px|This caption has [irc://example.net irc] and [https://example.com Secure] ext links in it.]] -!! result -
This caption has irc and Secure ext links in it.
- -!! end - -!! test -Custom class -!! input -[[Image:foobar.jpg|a|class=b]] -!! result -

a -

-!! end - -!! article -File:Barfoo.jpg -!! text -#REDIRECT [[File:Barfoo.jpg]] -!! endarticle - -!! test -Redirected image -!! input -[[Image:Barfoo.jpg]] -!! result -

File:Barfoo.jpg -

-!! end - -!! test -Missing image with uploads disabled -!! options -wgEnableUploads=0 -!! input -[[Image:Foobaz.jpg]] -!! result -

File:Foobaz.jpg -

-!! end - - -### -### Subpages -### -!! article -Subpage test/subpage -!! text -foo -!! endarticle - -!! test -Subpage link -!! options -subpage title=[[Subpage test]] -!! input -[[/subpage]] -!! result -

/subpage -

-!! end - -!! test -Subpage noslash link -!! options -subpage title=[[Subpage test]] -!!input -[[/subpage/]] -!! result -

subpage -

-!! end - -!! test -Disabled subpages -!! input -[[/subpage]] -!! result -

/subpage -

-!! end - -!! test -BUG 561: {{/Subpage}} -!! options -subpage title=[[Page]] -!! input -{{/Subpage}} -!! result -

Page/Subpage -

-!! end - -### -### Categories -### -!! article -Category:MediaWiki User's Guide -!! text -blah -!! endarticle - -!! test -Link to category -!! input -[[:Category:MediaWiki User's Guide]] -!! result -

Category:MediaWiki User's Guide -

-!! end - -!! test -Simple category -!! options -cat -!! input -[[Category:MediaWiki User's Guide]] -!! result -MediaWiki User's Guide -!! end - -!! test -PAGESINCATEGORY invalid title fatal (r33546 fix) -!! input -{{PAGESINCATEGORY:}} -!! result -

0 -

-!! end - -### -### Inter-language links -### -!! test -Inter-language links -!! options -ill -!! input -[[es:Alimento]] -[[fr:Nourriture]] -[[zh:食品]] -!! result -es:Alimento fr:Nourriture zh:食品 -!! end - -### -### Sections -### -!! test -Basic section headings -!! input -== Headline 1 == -Some text - -==Headline 2== -More -===Smaller headline=== -Blah blah -!! result -

[edit] Headline 1

-

Some text -

-

[edit] Headline 2

-

More -

-

[edit] Smaller headline

-

Blah blah -

-!! end - -!! test -Section headings with TOC -!! input -== Headline 1 == -=== Subheadline 1 === -===== Skipping a level ===== -====== Skipping a level ====== - -== Headline 2 == -Some text -===Another headline=== -!! result -

Contents

- -
-

[edit] Headline 1

-

[edit] Subheadline 1

-
[edit] Skipping a level
-
[edit] Skipping a level
-

[edit] Headline 2

-

Some text -

-

[edit] Another headline

- -!! end - -# perl -e 'print "="x$_," Level $_ heading","="x$_,"\n" for 1..10' -!! test -Handling of sections up to level 6 and beyond -!! input -= Level 1 Heading= -== Level 2 Heading== -=== Level 3 Heading=== -==== Level 4 Heading==== -===== Level 5 Heading===== -====== Level 6 Heading====== -======= Level 7 Heading======= -======== Level 8 Heading======== -========= Level 9 Heading========= -========== Level 10 Heading========== -!! result -

Contents

- -
-

[edit] Level 1 Heading

-

[edit] Level 2 Heading

-

[edit] Level 3 Heading

-

[edit] Level 4 Heading

-
[edit] Level 5 Heading
-
[edit] Level 6 Heading
-
[edit] = Level 7 Heading=
-
[edit] == Level 8 Heading==
-
[edit] === Level 9 Heading===
-
[edit] ==== Level 10 Heading====
- -!! end - -!! test -TOC regression (bug 9764) -!! input -== title 1 == -=== title 1.1 === -==== title 1.1.1 ==== -=== title 1.2 === -== title 2 == -=== title 2.1 === -!! result -

Contents

- -
-

[edit] title 1

-

[edit] title 1.1

-

[edit] title 1.1.1

-

[edit] title 1.2

-

[edit] title 2

-

[edit] title 2.1

- -!! end - -!! test -TOC with wgMaxTocLevel=3 (bug 6204) -!! options -wgMaxTocLevel=3 -!! input -== title 1 == -=== title 1.1 === -==== title 1.1.1 ==== -=== title 1.2 === -== title 2 == -=== title 2.1 === -!! result -

Contents

- -
-

[edit] title 1

-

[edit] title 1.1

-

[edit] title 1.1.1

-

[edit] title 1.2

-

[edit] title 2

-

[edit] title 2.1

- -!! end - -!! test -TOC with wgMaxTocLevel=3 and two level four headings (bug 6204) -!! options -wgMaxTocLevel=3 -!! input -==Section 1== -===Section 1.1=== -====Section 1.1.1==== -====Section 1.1.1.1==== -==Section 2== -!! result -

Contents

- -
-

[edit] Section 1

-

[edit] Section 1.1

-

[edit] Section 1.1.1

-

[edit] Section 1.1.1.1

-

[edit] Section 2

- -!! end - - -!! test -Resolving duplicate section names -!! input -== Foo bar == -== Foo bar == -!! result -

[edit] Foo bar

-

[edit] Foo bar

- -!! end - -!! test -Resolving duplicate section names with differing case (bug 10721) -!! input -== Foo bar == -== Foo Bar == -!! result -

[edit] Foo bar

-

[edit] Foo Bar

- -!! end - -!! article -Template:sections -!! text -===Section 1=== -==Section 2== -!! endarticle - -!! test -Template with sections, __NOTOC__ -!! input -__NOTOC__ -==Section 0== -{{sections}} -==Section 4== -!! result -

[edit] Section 0

-

[edit] Section 1

-

[edit] Section 2

-

[edit] Section 4

- -!! end - -!! test -__NOEDITSECTION__ keyword -!! input -__NOEDITSECTION__ -==Section 1== -==Section 2== -!! result -

Section 1

-

Section 2

- -!! end - -!! test -Link inside a section heading -!! input -==Section with a [[Main Page|link]] in it== -!! result -

[edit] Section with a link in it

- -!! end - -!! test -TOC regression (bug 12077) -!! input -__TOC__ -== title 1 == -=== title 1.1 === -== title 2 == -!! result -

Contents

- -
-

[edit] title 1

-

[edit] title 1.1

-

[edit] title 2

- -!! end - -!! test -BUG 1219 URL next to image (good) -!! input -http://example.com [[Image:foobar.jpg]] -!! result -

http://example.com Foobar.jpg -

-!!end - -!! test -Short headings with trailing space should match behaviour of Parser::doHeadings (bug 19910) -!! input -=== -The line above must have a trailing space! -=== -But just in case it doesn't... -!! result -

[edit] =

-

The line above must have a trailing space! -

-

[edit] =

-

But just in case it doesn't... -

-!! end - -!! test -Header with special characters (bug 25462) -!! input -The tooltips shall not show entities to the user (ie. be double escaped) - -== text > text == -section 1 - -== text < text == -section 2 - -== text & text == -section 3 - -== text ' text == -section 4 - -== text " text == -section 5 -!! result -

The tooltips shall not show entities to the user (ie. be double escaped) -

-

Contents

- -
-

[edit] text > text

-

section 1 -

-

[edit] text < text

-

section 2 -

-

[edit] text & text

-

section 3 -

-

[edit] text ' text

-

section 4 -

-

[edit] text " text

-

section 5 -

-!! end - -!! test -Headers with excess '=' characters -(Are similar tests necessary beyond the 1st level?) -!! input -=foo== -==foo= -=''italic'' heading== -==''italic'' heading= -!! result -

Contents

- -
-

[edit] foo=

-

[edit] =foo

-

[edit] italic heading=

-

[edit] =italic heading

- -!! end - -!! test -BUG 1219 URL next to image (broken) -!! input -http://example.com[[Image:foobar.jpg]] -!! result -

http://example.comFoobar.jpg -

-!!end - -!! test -Bug 1186 news: in the middle of text -!! input -http://en.wikinews.org/wiki/Wikinews:Workplace -!! result -

http://en.wikinews.org/wiki/Wikinews:Workplace -

-!!end - - -!! test -Namespaced link must have a title -!! input -[[Project:]] -!! result -

[[Project:]] -

-!!end - -!! test -Namespaced link must have a title (bad fragment version) -!! input -[[Project:#fragment]] -!! result -

[[Project:#fragment]] -

-!!end - - -!! test -div with no attributes -!! input -
HTML rocks
-!! result -
HTML rocks
- -!! end - -!! test -div with double-quoted attribute -!! input -
HTML rocks
-!! result -
HTML rocks
- -!! end - -!! test -div with single-quoted attribute -!! input -
HTML rocks
-!! result -
HTML rocks
- -!! end - -!! test -div with unquoted attribute -!! input -
HTML rocks
-!! result -
HTML rocks
- -!! end - -!! test -div with illegal double attributes -!! input -
HTML rocks
-!! result -
HTML rocks
- -!!end - -!! test -HTML multiple attributes correction -!! input -

Awesome!

-!! result -

Awesome!

- -!!end - -!! test -Table multiple attributes correction -!! input -{| -!+ class="error" class="awesome"| status -|} -!! result - - -
status -
- -!!end - -!! test -DIV IN UPPERCASE -!! input -
HTML ROCKS
-!! result -
HTML ROCKS
- -!!end - - -!! test -text with amp in the middle of nowhere -!! input -Remember AT&T? -!!result -

Remember AT&T? -

-!! end - -!! test -text with character entity: eacute -!! input -I always thought é was a cute letter. -!! result -

I always thought é was a cute letter. -

-!! end - -!! test -text with undefined character entity: xacute -!! input -I always thought &xacute; was a cute letter. -!! result -

I always thought &xacute; was a cute letter. -

-!! end - - -### -### Media links -### - -!! test -Media link -!! input -[[Media:Foobar.jpg]] -!! result -

Media:Foobar.jpg -

-!! end - -!! test -Media link with text -!! input -[[Media:Foobar.jpg|A neat file to look at]] -!! result -

A neat file to look at -

-!! end - -# FIXME: this is still bad HTML tag nesting -!! test -Media link with nasty text -fixme: doBlockLevels won't wrap this in a paragraph because it contains a div -!! input -[[Media:Foobar.jpg|Safe Link
" onmouseover="alert(document.cookie)" onfoo="
]] -!! result -Safe Link<div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div> - -!! end - -!! test -Media link to nonexistent file (bug 1702) -!! input -[[Media:No such.jpg]] -!! result -

Media:No such.jpg -

-!! end - -!! test -Image link to nonexistent file (bug 1850 - good) -!! input -[[Image:No such.jpg]] -!! result -

File:No such.jpg -

-!! end - -!! test -:Image link to nonexistent file (bug 1850 - bad) -!! input -[[:Image:No such.jpg]] -!! result -

Image:No such.jpg -

-!! end - - - -!! test -Character reference normalization in link text (bug 1938) -!! input -[[Main Page|this&that]] -!! result -

this&that -

-!!end - -!! article -אַ -!! text -Test for unicode normalization - -The page's name is U+05d0 U+05b7, with non-canonical form U+FB2E -!! endarticle - -!! test -(bug 19451) Links should refer to the normalized form. -!! input -[[אַ]] -[[אַ]] -[[אַ]] -[[אַ]] -[[אַ]] -!! result -

-אַ -אַ -אַ -אַ -

-!! end - -!! test -Empty attribute crash test (bug 2067) -!! input -foo -!! result -

foo -

-!! end - -!! test -Empty attribute crash test single-quotes (bug 2067) -!! input -foo -!! result -

foo -

-!! end - -!! test -Attribute test: equals, then nothing -!! input -foo -!! result -

foo -

-!! end - -!! test -Attribute test: unquoted value -!! input -foo -!! result -

foo -

-!! end - -!! test -Attribute test: unquoted but illegal value (hash) -!! input -foo -!! result -

foo -

-!! end - -!! test -Attribute test: no value -!! input -foo -!! result -

foo -

-!! end - -!! test -Bug 2095: link with three closing brackets -!! input -[[Main Page]]] -!! result -

Main Page] -

-!! end - -!! test -Bug 2095: link with pipe and three closing brackets -!! input -[[Main Page|link]]] -!! result -

link] -

-!! end - -!! test -Bug 2095: link with pipe and three closing brackets, version 2 -!! input -[[Main Page|[http://example.com/]]] -!! result -

[http://example.com/] -

-!! end - - -### -### Safety -### - -!! article -Template:Dangerous attribute -!! text -" onmouseover="alert(document.cookie) -!! endarticle - -!! article -Template:Dangerous style attribute -!! text -border-size: expression(alert(document.cookie)) -!! endarticle - -!! article -Template:Div style -!! text -
Magic div
-!! endarticle - -!! test -Bug 2304: HTML attribute safety (safe template; regression bug 2309) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (dangerous template; 2309) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (dangerous style template; 2309) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (safe parameter; 2309) -!! input -{{div style|width: 200px}} -!! result -
Magic div
- -!! end - -!! test -Bug 2304: HTML attribute safety (unsafe parameter; 2309) -!! input -{{div style|width: expression(alert(document.cookie))}} -!! result -
Magic div
- -!! end - -!! test -Bug 2304: HTML attribute safety (unsafe breakout parameter; 2309) -!! input -{{div style|">}} -!! result -
<script>alert(document.cookie)</script>">Magic div
- -!! end - -!! test -Bug 2304: HTML attribute safety (unsafe breakout parameter 2; 2309) -!! input -{{div style|" >}} -!! result -
<script>alert(document.cookie)</script>">Magic div
- -!! end - -!! test -Bug 2304: HTML attribute safety (link) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (italics) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (bold) -!! input -
-!! result -
- -!! end - - -!! test -Bug 2304: HTML attribute safety (ISBN) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (RFC) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (PMID) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (web link) -!! input -
-!! result -
- -!! end - -!! test -Bug 2304: HTML attribute safety (named web link) -!! input -
-!! result -
- -!! end - -!! test -Bug 3244: HTML attribute safety (extension; safe) -!! input -
-!! result -
- -!! end - -!! test -Bug 3244: HTML attribute safety (extension; unsafe) -!! input -
-!! result -
- -!! end - -# More MSIE fun discovered by Tom Gilder - -!! test -MSIE CSS safety test: spurious slash -!! input -
evil
-!! result -
evil
- -!! end - -!! test -MSIE CSS safety test: hex code -!! input -
evil
-!! result -
evil
- -!! end - -!! test -MSIE CSS safety test: comment in url -!! input -
evil
-!! result -
evil
- -!! end - -!! test -MSIE CSS safety test: comment in expression -!! input -
evil4
-!! result -
evil4
- -!! end - - -!! test -Table attribute legitimate extension -!! input -{| -!+ style="color:blue"| status -|} -!! result - - -
status -
- -!!end - -!! test -Table attribute safety -!! input -{| -!+ style="border-width:expression(0+alert(document.cookie))"| status -|} -!! result - - -
status -
- -!! end - -!! test -CSS line continuation 1 -!! input -
-!! result -
- -!! end - -!! test -CSS line continuation 2 -!! input -
-!! result -
- -!! end - -!! article -Template:Identity -!! text -{{{1}}} -!! endarticle - -!! test -Expansion of multi-line templates in attribute values (bug 6255) -!! input -
-
-!! result -
-
- -!! end - - -!! test -Expansion of multi-line templates in attribute values (bug 6255 sanity check) -!! input -
-
-!! result -
-
- -!! end - -!! test -Expansion of multi-line templates in attribute values (bug 6255 sanity check 2) -!! input -
-
-!! result -
-
- -!! end - -### -### Parser hooks (see maintenance/parserTestsParserHook.php for the extension) -### -!! test -Parser hook: empty input -!! input - -!! result -
-string(0) ""
-array(0) {
-}
-
- -!! end - -!! test -Parser hook: empty input using terminated empty elements -!! input - -!! result -
-NULL
-array(0) {
-}
-
- -!! end - -!! test -Parser hook: empty input using terminated empty elements (space before) -!! input - -!! result -
-NULL
-array(0) {
-}
-
- -!! end - -!! test -Parser hook: basic input -!! input -input -!! result -
-string(5) "input"
-array(0) {
-}
-
- -!! end - - -!! test -Parser hook: case insensitive -!! input -input -!! result -
-string(5) "input"
-array(0) {
-}
-
- -!! end - - -!! test -Parser hook: case insensitive, redux -!! input -input -!! result -
-string(5) "input"
-array(0) {
-}
-
- -!! end - -!! test -Parser hook: nested tags -!! options -noxml -!! input - -!! result -
-string(5) ""
-array(0) {
-}
-
</tag> - -!! end - -!! test -Parser hook: basic arguments -!! input - -!! result -
-string(0) ""
-array(4) {
-  ["width"]=>
-  string(3) "200"
-  ["height"]=>
-  string(3) "100"
-  ["depth"]=>
-  string(2) "50"
-  ["square"]=>
-  string(6) "square"
-}
-
- -!! end - -!! test -Parser hook: argument containing a forward slash (bug 5344) -!! input - -!! result -
-string(0) ""
-array(1) {
-  ["filename"]=>
-  string(8) "/tmp/bla"
-}
-
- -!! end - -!! test -Parser hook: empty input using terminated empty elements (bug 2374) -!! input -text -!! result -
-NULL
-array(1) {
-  ["foo"]=>
-  string(3) "bar"
-}
-
text - -!! end - -#
should be output literally since there is no matching tag that begins it -!! test -Parser hook: basic arguments using terminated empty elements (bug 2374) -!! input - -other stuff - -!! result -
-NULL
-array(4) {
-  ["width"]=>
-  string(3) "200"
-  ["height"]=>
-  string(3) "100"
-  ["depth"]=>
-  string(2) "50"
-  ["square"]=>
-  string(6) "square"
-}
-
-

other stuff -</tag> -

-!! end - -### -### (see maintenance/parserTestsStaticParserHook.php for the extension) -### - -!! test -Parser hook: static parser hook not inside a comment -!! input -hello, world - -!! result -

hello, world -

-!! end - - -!! test -Parser hook: static parser hook inside a comment -!! input - - -!! result -


-

-!! end - -# Nested template calls; this case was broken by Parser.php rev 1.506, -# since reverted. - -!! article -Template:One-parameter -!! text -(My parameter is: {{{1}}}) -!! endarticle - -!! article -Template:Map-one-parameter -!! text -{{{{{1}}}|{{{2}}}}} -!! endarticle - -!! test -Nested template calls -!! input -{{Map-one-parameter|One-parameter|param}} -!! result -

(My parameter is: param) -

-!! end - - -### -### Sanitizer -### -!! test -Sanitizer: Closing of open tags -!! input -
-!! result -
- -!! end - -!! test -Sanitizer: Closing of open but not closed tags -!! input -foo -!! result -

foo -

-!! end - -!! test -Sanitizer: Closing of closed but not open tags -!! input -
-!! result -

</s> -

-!! end - -!! test -Sanitizer: Closing of closed but not open table tags -!! input -Table not started -!! result -

Table not started</td></tr></table> -

-!! end - -!! test -Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id="" -!! input -byte[[#æ: v|backlink]] -!! result -

bytebacklink -

-!! end - -!! test -Sanitizer: Validating the contents of the id attribute (bug 4515) -!! options -disabled -!! input -
-!! result -Something, but definitely not
... -!! end - -!! test -Sanitizer: Validating id attribute uniqueness (bug 4515, bug 6301) -!! options -disabled -!! input -

-!! result -Something need to be done. foo-2 ? -!! end - -!! test -Language converter: output gets cut off unexpectedly (bug 5757) -!! options -language=zh -!! input -this bit is safe: }- - -but if we add a conversion instance: -{zh-cn:xxx;zh-tw:yyy}- - -then we get cut off here: }- - -all additional text is vanished -!! result -

this bit is safe: }- -

but if we add a conversion instance: xxx -

then we get cut off here: }- -

all additional text is vanished -

-!! end - -!! test -Self closed html pairs (bug 5487) -!! options -!! input -
Centered text
-
In div text
-!! result -
<font id="bug" />Centered text
-
<font id="bug2" />In div text
- -!! end - -# -# -# - -!! test -Punctuation: nbsp before exclamation -!! input -C'est grave ! -!! result -

C'est grave ! -

-!! end - -!! test -Punctuation: CSS !important (bug 11874) -!! input -
important
-!! result -
important
- -!!end - -!! test -Punctuation: CSS ! important (bug 11874; with space after) -!! input -
important
-!! result -
important
- -!!end - - -!! test -HTML bullet list, closed tags (bug 5497) -!! input -
    -
  • One
  • -
  • Two
  • -
-!! result -
    -
  • One
  • -
  • Two
  • -
- -!! end - -!! test -HTML bullet list, unclosed tags (bug 5497) -!! options -disabled -!! input -
    -
  • One -
  • Two -
-!! result -
    -
  • One -
  • Two -
- -!! end - -!! test -HTML ordered list, closed tags (bug 5497) -!! input -
    -
  1. One
  2. -
  3. Two
  4. -
-!! result -
    -
  1. One
  2. -
  3. Two
  4. -
- -!! end - -!! test -HTML ordered list, unclosed tags (bug 5497) -!! options -disabled -!! input -
    -
  1. One -
  2. Two -
-!! result -
    -
  1. One -
  2. Two -
- -!! end - -!! test -HTML nested bullet list, closed tags (bug 5497) -!! input -
    -
  • One
  • -
  • Two: -
      -
    • Sub-one
    • -
    • Sub-two
    • -
    -
  • -
-!! result -
    -
  • One
  • -
  • Two: -
      -
    • Sub-one
    • -
    • Sub-two
    • -
    -
  • -
- -!! end - -!! test -HTML nested bullet list, open tags (bug 5497) -!! options -disabled -!! input -
    -
  • One -
  • Two: -
      -
    • Sub-one -
    • Sub-two -
    -
-!! result -
    -
  • One -
  • Two: -
      -
    • Sub-one -
    • Sub-two -
    -
- -!! end - -!! test -HTML nested ordered list, closed tags (bug 5497) -!! input -
    -
  1. One
  2. -
  3. Two: -
      -
    1. Sub-one
    2. -
    3. Sub-two
    4. -
    -
  4. -
-!! result -
    -
  1. One
  2. -
  3. Two: -
      -
    1. Sub-one
    2. -
    3. Sub-two
    4. -
    -
  4. -
- -!! end - -!! test -HTML nested ordered list, open tags (bug 5497) -!! options -disabled -!! input -
    -
  1. One -
  2. Two: -
      -
    1. Sub-one -
    2. Sub-two -
    -
-!! result -
    -
  1. One -
  2. Two: -
      -
    1. Sub-one -
    2. Sub-two -
    -
- -!! end - -!! test -HTML ordered list item with parameters oddity -!! input -
  1. One
-!! result -
  1. One
- -!! end - -!!test -bug 5918: autonumbering -!! input -[http://first/] [http://second] [ftp://ftp] - -ftp://inlineftp - -[mailto:enclosed@mail.tld With target] - -[mailto:enclosed@mail.tld] - -mailto:inline@mail.tld -!! result -

[1] [2] [3] -

ftp://inlineftp -

With target -

[4] -

mailto:inline@mail.tld -

-!! end - - -# -# Security and HTML correctness -# From Nick Jenkins' fuzz testing -# - -!! test -Fuzz testing: Parser13 -!! input -{| -| http://a| -!! result - - - - -
-
- -!! end - -!! test -Fuzz testing: Parser14 -!! input -== onmouseover= == -http://__TOC__ -!! result -

[edit] onmouseover=

-http://

Contents

- -
- -!! end - -!! test -Fuzz testing: Parser14-table -!! input -==a== -{| STYLE=__TOC__ -!! result -

[edit] a

- - -
- -!! end - -# Known to produce bogus xml (extra ) -!! test -Fuzz testing: Parser16 -!! options -noxml -!! input -{| -!https://|||||| -!! result - - - - - - -
https:// - -
- -!! end - -!! test -Fuzz testing: Parser21 -!! input -{| -! irc://{{ftp://a" onmouseover="alert('hello world');" -| -!! result - - - - - -
irc://{{ftp://a" onmouseover="alert('hello world');" - -
- -!! end - -!! test -Fuzz testing: Parser22 -!! input -http://===r:::https://b - -{| -!!result -

http://===r:::https://b -

- - -
- -!! end - -# Known to produce bad XML for now -!! test -Fuzz testing: Parser24 -!! options -noxml -!! input -{| -{{{| -}}}} > -
- -MOVE YOUR MOUSE CURSOR OVER THIS TEXT -| -!! result - -{{{| -}}}} > -
- -MOVE YOUR MOUSE CURSOR OVER THIS TEXT -
- - -
-
- -!! end - -# Note: the current result listed for this is not what the original one was, -# but the original bug was JavaScript injection, which is fixed in any case. -# It's not clear that the original result listed was any more correct than the -# current one. Original result: -#

{{{| -#

-#
  • -# }}}blah" onmouseover="alert('hello world');" align="left"MOVE MOUSE CURSOR OVER HERE -!!test -Fuzz testing: Parser25 (bug 6055) -!! input -{{{ -| -
  • -}}}blah" onmouseover="alert('hello world');" align="left"'''MOVE MOUSE CURSOR OVER HERE -!! result -

    <LI CLASS=blah" onmouseover="alert('hello world');" align="left"MOVE MOUSE CURSOR OVER HERE -

    -!! end - -!!test -Fuzz testing: URL adjacent extension (with space, clean) -!! options -!! input -http://example.com junk -!! result -

    http://example.com junk -

    -!!end - -!!test -Fuzz testing: URL adjacent extension (no space, dirty; nowiki) -!! options -!! input -http://example.comjunk -!! result -

    http://example.comjunk -

    -!!end - -!!test -Fuzz testing: URL adjacent extension (no space, dirty; pre) -!! options -!! input -http://example.com
    junk
    -!! result -http://example.com
    junk
    - -!!end - -!!test -Fuzz testing: image with bogus manual thumbnail -!!input -[[Image:foobar.jpg|thumbnail= ]] -!!result -
    Error creating thumbnail:
    - -!!end - -!! test -Fuzz testing: encoded newline in generated HTML replacements (bug 6577) -!! input -
    
    -!! result
    -
    
    -
    -!! end
    -
    -!! test
    -Parsing optional HTML elements (Bug 6171)
    -!! options
    -!! input
    -
    -  
    -    
    -    
    -  
    -
    Some tabular data More tabular data ... - And yet som tabular data
    -!! result - - - - - -
    Some tabular data More tabular data ... - And yet som tabular data
    - -!! end - -!! test -Correct handling of , (Bug 6171) -!! options -!! input - - - - - - -
    Some tabular data More tabular data ... And yet som tabular data
    -!! result - - - - - - -
    Some tabular data More tabular data ... And yet som tabular data
    - -!! end - - -!! test -Parsing crashing regression (fr:JavaScript) -!! input - -!! result -

    </body></x> -

    -!! end - -!! test -Inline wiki vs wiki block nesting -!! input -'''Bold paragraph - -New wiki paragraph -!! result -

    Bold paragraph -

    New wiki paragraph -

    -!! end - -!! test -Inline HTML vs wiki block nesting -!! options -disabled -!! input -Bold paragraph - -New wiki paragraph -!! result -

    Bold paragraph -

    New wiki paragraph -

    -!! end - -# Original result was this: -#

    boldboldbolditalics -#

    -# While that might be marginally more intuitive, maybe, the six-apostrophe -# construct is clearly pathological and the result stated here (which is what -# the parser actually does) is about as reasonable as anything. -!!test -Mixing markup for italics and bold -!! options -!! input -'''bold''''''bold''bolditalics''''' -!! result -

    'bold'boldbolditalics -

    -!! end - - -!! article -Xyzzyx -!! text -Article for special page transclusion test -!! endarticle - -!! test -Special page transclusion -!! options -!! input -{{Special:Prefixindex/Xyzzyx}} -!! result -
    Xyzzyx
    - -!! end - -!! test -Special page transclusion twice (bug 5021) -!! options -!! input -{{Special:Prefixindex/Xyzzyx}} -{{Special:Prefixindex/Xyzzyx}} -!! result -
    Xyzzyx
    -
    Xyzzyx
    - -!! end - -!! test -Transclusion of default MediaWiki message -!! input -{{MediaWiki:Mainpage}} -!!result -

    Main Page -

    -!! end - -!! test -Transclusion of nonexistent MediaWiki message -!! input -{{MediaWiki:Mainpagexxx}} -!!result -

    MediaWiki:Mainpagexxx -

    -!! end - -!! test -Transclusion of MediaWiki message with underscore -!! input -{{MediaWiki:history_short}} -!! result -

    History -

    -!! end - -!! test -Transclusion of MediaWiki message with space -!! input -{{MediaWiki:history short}} -!! result -

    History -

    -!! end - -!! test -Invalid header with following text -!! input -= x = y -!! result -

    = x = y -

    -!! end - - -!! test -Section extraction test (section 0) -!! options -section=0 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -!! end - -!! test -Section extraction test (section 1) -!! options -section=1 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -==a== -===aa=== -====aaa==== -!! end - -!! test -Section extraction test (section 2) -!! options -section=2 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -===aa=== -====aaa==== -!! end - -!! test -Section extraction test (section 3) -!! options -section=3 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -====aaa==== -!! end - -!! test -Section extraction test (section 4) -!! options -section=4 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -==b== -===ba=== -===bb=== -====bba==== -===bc=== -!! end - -!! test -Section extraction test (section 5) -!! options -section=5 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -===ba=== -!! end - -!! test -Section extraction test (section 6) -!! options -section=6 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -===bb=== -====bba==== -!! end - -!! test -Section extraction test (section 7) -!! options -section=7 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -====bba==== -!! end - -!! test -Section extraction test (section 8) -!! options -section=8 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -===bc=== -!! end - -!! test -Section extraction test (section 9) -!! options -section=9 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -==c== -===ca=== -!! end - -!! test -Section extraction test (section 10) -!! options -section=10 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -===ca=== -!! end - -!! test -Section extraction test (nonexistent section 11) -!! options -section=11 -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -!! end - -!! test -Section extraction test with bogus heading (section 1) -!! options -section=1 -!! input -==a== -==bogus== not a legal section -==b== -!! result -==a== -==bogus== not a legal section -!! end - -!! test -Section extraction test with bogus heading (section 2) -!! options -section=2 -!! input -==a== -==bogus== not a legal section -==b== -!! result -==b== -!! end - -!! test -Section extraction test with comment after heading (section 1) -!! options -section=1 -!! input -==a== -==b== -==c== -!! result -==a== -!! end - -!! test -Section extraction test with comment after heading (section 2) -!! options -section=2 -!! input -==a== -==b== -==c== -!! result -==b== -!! end - -!! test -Section extraction test with bogus heading (section 1) -!! options -section=1 -!! input -==a== -==bogus== not a legal section -==b== -!! result -==a== -==bogus== not a legal section -!! end - -!! test -Section extraction test with bogus heading (section 2) -!! options -section=2 -!! input -==a== -==bogus== not a legal section -==b== -!! result -==b== -!! end - - -# Formerly testing for bug 2587, now resolved by the use of unmarked sections -# instead of respecting commented sections -!! test -Section extraction prefixed by comment (section 1) -!! options -section=1 -!! input -==sec1== -==sec2== -!!result -==sec2== -!!end - -!! test -Section extraction prefixed by comment (section 2) -!! options -section=2 -!! input -==sec1== -==sec2== -!!result - -!!end - - -# Formerly testing for bug 2607, now resolved by the use of unmarked sections -# instead of respecting HTML-style headings -!! test -Section extraction, mixed wiki and html (section 1) -!! options -section=1 -!! input -

    unmarked

    -unmarked -==1== -one -==2== -two -!! result -==1== -one -!! end - -!! test -Section extraction, mixed wiki and html (section 2) -!! options -section=2 -!! input -

    unmarked

    -unmarked -==1== -one -==2== -two -!! result -==2== -two -!! end - - -# Formerly testing for bug 3342 -!! test -Section extraction, heading surrounded by -!! options -section=1 -!! input -==unmarked== -==marked== -!! result -==marked== -!!end - -# Test behaviour of bug 19910 -!! test -Sectiion with all-equals -!! options -section=2 -!! input -=== -The line above must have a trailing space -=== -But just in case it doesn't... -!! result -=== -But just in case it doesn't... -!! end - -!! test -Section replacement test (section 0) -!! options -replace=0,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -xxx - -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 1) -!! options -replace=1,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -xxx - -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 2) -!! options -replace=2,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -xxx - -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 3) -!! options -replace=3,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -xxx - -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 4) -!! options -replace=4,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -xxx - -==c== -===ca=== -!! end - -!! test -Section replacement test (section 5) -!! options -replace=5,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -xxx - -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 6) -!! options -replace=6,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -xxx - -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 7) -!! options -replace=7,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -xxx - -===bc=== -==c== -===ca=== -!! end - -!! test -Section replacement test (section 8) -!! options -replace=8,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -xxx - -==c== -===ca=== -!!end - -!! test -Section replacement test (section 9) -!! options -replace=9,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -xxx -!! end - -!! test -Section replacement test (section 10) -!! options -replace=10,"xxx" -!! input -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -===ca=== -!! result -start -==a== -===aa=== -====aaa==== -==b== -===ba=== -===bb=== -====bba==== -===bc=== -==c== -xxx -!! end - -!! test -Section replacement test with initial whitespace (bug 13728) -!! options -replace=2,"xxx" -!! input - Preformatted initial line -==a== -===a=== -!! result - Preformatted initial line -==a== -xxx -!! end - - -!! test -Section extraction, heading followed by pre with 20 spaces (bug 6398) -!! options -section=1 -!! input -==a== - a -!! result -==a== - a -!! end - -!! test -Section extraction, heading followed by pre with 19 spaces (bug 6398 sanity check) -!! options -section=1 -!! input -==a== - a -!! result -==a== - a -!! end - - -!! test -Section extraction,
     around bogus header (bug 10309)
    -!! options
    -noxml section=2
    -!! input
    -== Section One ==
    -
    -=======
    -
    - -== Section Two == -stuff -!! result -== Section Two == -stuff -!! end - -!! test -Section replacement,
     around bogus header (bug 10309)
    -!! options
    -noxml replace=2,"xxx"
    -!! input
    -== Section One ==
    -
    -=======
    -
    - -== Section Two == -stuff -!! result -== Section One == -
    -=======
    -
    - -xxx -!! end - - - -!! test -Handling of in URLs -!! input -**irc:// a -!! result - - -!!end - -!! test -5 quotes, code coverage +1 line -!! input -''''' -!! result -!! end - -!! test -Special:Search page linking. -!! input -{{Special:search}} -!! result -

    Special:Search -

    -!! end - -!! test -Say the magic word -!! input -* {{PAGENAME}} -* {{BASEPAGENAME}} -* {{SUBPAGENAME}} -* {{SUBPAGENAMEE}} -* {{BASEPAGENAME}} -* {{BASEPAGENAMEE}} -* {{TALKPAGENAME}} -* {{TALKPAGENAMEE}} -* {{SUBJECTPAGENAME}} -* {{SUBJECTPAGENAMEE}} -* {{NAMESPACEE}} -* {{NAMESPACE}} -* {{TALKSPACE}} -* {{TALKSPACEE}} -* {{SUBJECTSPACE}} -* {{SUBJECTSPACEE}} -* {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}} -!! result -
    • Parser test -
    • Parser test -
    • Parser test -
    • Parser_test -
    • Parser test -
    • Parser_test -
    • Talk:Parser test -
    • Talk:Parser_test -
    • Parser test -
    • Parser_test -
    • -
    • -
    • Talk -
    • Talk -
    • -
    • -
    • Template:Dynamic -
    - -!! end -### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included. - -!! test -Gallery -!! input - -image1.png | -image2.gif||||| - -image3| -image4 |300px| centre - image5.svg| http:///////// -[[x|xx]]]] -* image6 - -!! result - - -!! end - -!! test -Gallery (with options) -!! input - -File:Nonexistant.jpg|caption -File:Nonexistant.jpg -image:foobar.jpg|some '''caption''' [[Main Page]] -image:foobar.jpg -image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla. - -!! result - - -!! end - -!! test -Gallery with wikitext inside caption -!! input - -File:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=inneralt]]|alt=galleryalt -File:foobar.jpg|{{Test|unamedParam|alt=param}}|alt=galleryalt - -!! result - - -!! end - -!! test -gallery (with showfilename option) -!! input - -File:Nonexistant.jpg|caption -File:Nonexistant.jpg -image:foobar.jpg|some '''caption''' [[Main Page]] -File:Foobar.jpg - -!! result - - -!! end - -!! test -Gallery (with namespace-less filenames) -!! input - -File:Nonexistant.jpg -Nonexistant.jpg -image:foobar.jpg -foobar.jpg - -!! result - - -!! end - -!! test -HTML Hex character encoding (spells the word "JavaScript") -!! input -JavaScript -!! result -

    JavaScript -

    -!! end - -!! test -HTML Hex character encoding bogus encoding (bug 26437 regression check) -!! input -&#xsee;&#XSEE; -!! result -

    &#xsee;&#XSEE; -

    -!! end - -!! test -HTML Hex character encoding mixed case -!! input -îî -!! result -

    îî -

    -!! end - -!! test -__FORCETOC__ override -!! input -__NEWSECTIONLINK__ -__FORCETOC__ -!! result -


    -

    -!! end - -!! test -ISBN code coverage -!! input -ISBN 978-0-1234-56 789 -!! result -

    ISBN 978-0-1234-56 789 -

    -!! end - -!! test -ISBN followed by 5 spaces -!! input -ISBN -!! result -

    ISBN -

    -!! end - -!! test -Double ISBN -!! input -ISBN ISBN 1234567890 -!! result -

    ISBN ISBN 1234567890 -

    -!! end - -!! test -Bug 22905: followed by ISBN followed by -!! input -(fr) ISBN 2753300917 [http://www.example.com example.com] -!! result -

    (fr) ISBN 2753300917 example.com -

    -!! end - -!! test -Double RFC -!! input -RFC RFC 1234 -!! result -

    RFC RFC 1234 -

    -!! end - -!! test -Double RFC with a wiki link -!! input -RFC [[RFC 1234]] -!! result -

    RFC RFC 1234 -

    -!! end - -!! test -RFC code coverage -!! input -RFC 983 987 -!! result -

    RFC 983 987 -

    -!! end - -!! test -Centre-aligned image -!! input -[[Image:foobar.jpg|centre]] -!! result -
    Foobar.jpg
    - -!!end - -!! test -None-aligned image -!! input -[[Image:foobar.jpg|none]] -!! result -
    Foobar.jpg
    - -!!end - -!! test -Width + Height sized image (using px) (height is ignored) -!! input -[[Image:foobar.jpg|640x480px]] -!! result -

    Foobar.jpg -

    -!!end - -!! test -Width-sized image (using px, no following whitespace) -!! input -[[Image:foobar.jpg|640px]] -!! result -

    Foobar.jpg -

    -!!end - -!! test -Width-sized image (using px, with following whitespace - test regression from r39467) -!! input -[[Image:foobar.jpg|640px ]] -!! result -

    Foobar.jpg -

    -!!end - -!! test -Width-sized image (using px, with preceding whitespace - test regression from r39467) -!! input -[[Image:foobar.jpg| 640px]] -!! result -

    Foobar.jpg -

    -!!end - -!! test -Another italics / bold test -!! input - ''' ''x' -!! result -
    ' x'
    -
    -!!end - -# Note the results may be incorrect, as parserTest output included this: -# XML error: Mismatched tag at byte 6120: -# ...
    -
    -
    -
    -
    -
    -
    - -!!end - - -# Images with the "|" character in external URLs in comment tags; Eats half the comment, leaves unmatched "" tag. -!! test -Images with the "|" character in the comment -!! input -[[image:Foobar.jpg|thumb|An [http://test/?param1=|left|¶m2=|x external] URL]] -!! result -
    An external URL
    - -!!end - -!! test -[Before] HTML without raw HTML enabled ($wgRawHtml==false) -!! input - -!! result -

    <html><script>alert(1);</script></html> -

    -!! end - -!! test -HTML with raw HTML ($wgRawHtml==true) -!! options -rawhtml -!! input - -!! result -

    -

    -!! end - -!! test -Parents of subpages, one level up -!! options -subpage title=[[Subpage test/L1/L2/L3]] -!! input -[[../|L2]] -!! result -

    L2 -

    -!! end - - -!! test -Parents of subpages, one level up, not named -!! options -subpage title=[[Subpage test/L1/L2/L3]] -!! input -[[../]] -!! result -

    Subpage test/L1/L2 -

    -!! end - - - -!! test -Parents of subpages, two levels up -!! options -subpage title=[[Subpage test/L1/L2/L3]] -!! input -[[../../|L1]]2 - -[[../../|L1]]l -!! result -

    L12 -

    L1l -

    -!! end - -!! test -Parents of subpages, two levels up, without trailing slash or name. -!! options -subpage title=[[Subpage test/L1/L2/L3]] -!! input -[[../..]] -!! result -

    [[../..]] -

    -!! end - -!! test -Parents of subpages, two levels up, with lots of extra trailing slashes. -!! options -subpage title=[[Subpage test/L1/L2/L3]] -!! input -[[../../////]] -!! result -

    /// -

    -!! end - -!! test -Definition list code coverage -!! input -; title : def -; title : def -;title: def -!! result -
    title  
    def -
    title 
    def -
    title
    def -
    - -!! end - -!! test -Don't fall for the self-closing div -!! input -
    hello world
    -!! result -
    hello world
    - -!! end - -!! test -MSGNW magic word -!! input -{{MSGNW:msg}} -!! result -

    [[:Template:Msg]] -

    -!! end - -!! test -RAW magic word -!! input -{{RAW:QUERTY}} -!! result -

    Template:QUERTY -

    -!! end - -# This isn't needed for XHTML conformance, but would be handy as a fallback security measure -!! test -Always escape literal '>' in output, not just after '<' -!! input -><> -!! result -

    ><> -

    -!! end - -!! test -Template caching -!! input -{{Test}} -{{Test}} -!! result -

    This is a test template -This is a test template -

    -!! end - - -!! article -MediaWiki:Fake -!! text -==header== -!! endarticle - -!! test -Inclusion of !userCanEdit() content -!! input -{{MediaWiki:Fake}} -!! result -

    [edit] header

    - -!! end - - -!! test -Out-of-order TOC heading levels -!! input -==2== -======6====== -===3=== -=1= -=====5===== -==2== -!! result -

    Contents

    - -
    -

    [edit] 2

    -
    [edit] 6
    -

    [edit] 3

    -

    [edit] 1

    -
    [edit] 5
    -

    [edit] 2

    - -!! end - - -!! test -ISBN with a dummy number -!! input -ISBN --- -!! result -

    ISBN --- -

    -!! end - - -!! test -ISBN with space-delimited number -!! input -ISBN 92 9017 032 8 -!! result -

    ISBN 92 9017 032 8 -

    -!! end - - -!! test -ISBN with multiple spaces, no number -!! input -ISBN foo -!! result -

    ISBN foo -

    -!! end - - -!! test -ISBN length -!! input -ISBN 123456789 - -ISBN 1234567890 - -ISBN 12345678901 -!! result -

    ISBN 123456789 -

    ISBN 1234567890 -

    ISBN 12345678901 -

    -!! end - - -!! test -ISBN with trailing year (bug 8110) -!! input -ISBN 1-234-56789-0 - 2006 - -ISBN 1 234 56789 0 - 2006 -!! result -

    ISBN 1-234-56789-0 - 2006 -

    ISBN 1 234 56789 0 - 2006 -

    -!! end - - -!! test -anchorencode -!! input -{{anchorencode:foo bar©#%n}} -!! result -

    foo_bar.C2.A9.23.25n -

    -!! end - -!! test -anchorencode trims spaces -!! input -{{anchorencode: __pretty__please__}} -!! result -

    pretty_please -

    -!! end - -!! test -anchorencode deals with links -!! input -{{anchorencode: [[hello|world]] [[hi]]}} -!! result -

    world_hi -

    -!! end - -!! test -anchorencode deals with templates -!! input -{{anchorencode: {{Foo}} }} -!! result -

    FOO -

    -!! end - -!! test -anchorencode encodes like the TOC generator: (bug 18431) -!! input -=== _ +:.3A%3A&&]] === -{{anchorencode: _ +:.3A%3A&&]] }} -__NOEDITSECTION__ -!! result -

    _ +:.3A%3A&&]]

    -

    .2B:.3A.253A.26.26.5D.5D -

    -!! end - -# Expected output in the following test is not necessarily expected (there -# should probably be

    tags inside the

    in the output) -- it's -# only testing for well-formedness. -!! test -Bug 6200: blockquotes and paragraph formatting -!! input -
    -foo -
    - -bar - - baz -!! result -
    -foo -
    -

    bar -

    -
    baz
    -
    -!! end - -!! test -Bug 8293: Use of center tag ruins paragraph formatting -!! input -
    -foo -
    - -bar - - baz -!! result -
    -

    foo -

    -
    -

    bar -

    -
    baz
    -
    -!! end - - -### -### Language variants related tests -### -!! test -Self-link in language variants -!! options -title=[[Dunav]] language=sr -!! input -Both [[Dunav]] and [[Дунав]] are names for this river. -!! result -

    Both Dunav and Дунав are names for this river. -

    -!!end - - -!! test -Link to pages in language variants -!! options -language=sr -!! input -Main Page can be written as [[Маин Паге]] -!! result -

    Main Page can be written as Маин Паге -

    -!!end - - -!! test -Multiple links to pages in language variants -!! options -language=sr -!! input -[[Main Page]] can be written as [[Маин Паге]] same as [[Маин Паге]]. -!! result -

    Main Page can be written as Маин Паге same as Маин Паге. -

    -!!end - - -!! test -Simple template in language variants -!! options -language=sr -!! input -{{тест}} -!! result -

    This is a test template -

    -!! end - - -!! test -Template with explicit namespace in language variants -!! options -language=sr -!! input -{{Template:тест}} -!! result -

    This is a test template -

    -!! end - - -!! test -Basic test for template parameter in language variants -!! options -language=sr -!! input -{{парамтест|param=foo}} -!! result -

    This is a test template with parameter foo -

    -!! end - - -!! test -Simple category in language variants -!! options -language=sr cat -!! input -[[Category:МедиаWики Усер'с Гуиде]] -!! result -MediaWiki User's Guide -!! end - - -!! test -Stripping -{}- tags (language variants) -!! options -language=sr -!! input -Latin proverb: -{Ne nuntium necare}- -!! result -

    Latin proverb: Ne nuntium necare -

    -!! end - - -!! test -Prevent conversion with -{}- tags (language variants) -!! options -language=sr variant=sr-ec -!! input -Latinski: -{Ne nuntium necare}- -!! result -

    Латински: Ne nuntium necare -

    -!! end - - -!! test -Prevent conversion of text with -{}- tags (language variants) -!! options -language=sr variant=sr-ec -!! input -Latinski: -{Ne nuntium necare}- -!! result -

    Латински: Ne nuntium necare -

    -!! end - - -!! test -Prevent conversion of links with -{}- tags (language variants) -!! options -language=sr variant=sr-ec -!! input --{[[Main Page]]}- -!! result -

    Main Page -

    -!! end - - -!! test --{}- tags within headlines (within html for parserConvert()) -!! options -language=sr variant=sr-ec -!! input -== -{Naslov}- == -!! result -

    [уреди] Naslov

    - -!! end - - -!! test -Explicit definition of language variant alternatives -!! options -language=zh variant=zh-tw -!! input --{zh:China;zh-tw:Taiwan}-, not China -!! result -

    Taiwan, not China -

    -!! end - - -!! test -Explicit session-wise language variant mapping (A flag and - flag) -!! options -language=zh variant=zh-tw -!! input -Taiwan is not China. -But -{A|zh:China;zh-tw:Taiwan}- is China, -(This-{-|zh:China;zh-tw:Taiwan}- should be stripped!) -and -{China}- is China. -!! result -

    Taiwan is not China. -But Taiwan is Taiwan, -(This should be stripped!) -and China is China. -

    -!! end - -!! test -Explicit session-wise language variant mapping (H flag for hide) -!! options -language=zh variant=zh-tw -!! input -(This-{H|zh:China;zh-tw:Taiwan}- should be stripped!) -Taiwan is China. -!! result -

    (This should be stripped!) -Taiwan is Taiwan. -

    -!! end - -!! test -Adding explicit conversion rule for title (T flag) -!! options -language=zh variant=zh-tw showtitle -!! input -Should be stripped-{T|zh:China;zh-tw:Taiwan}-! -!! result -Taiwan -

    Should be stripped! -

    -!! end - -!! test -Testing that changing the language variant here in the tests actually works -!! options -language=zh variant=zh showtitle -!! input -Should be stripped-{T|zh:China;zh-tw:Taiwan}-! -!! result -China -

    Should be stripped! -

    -!! end - -!! test -Bug 24072: more test on conversion rule for title -!! options -language=zh variant=zh-tw showtitle -!! input -This should be stripped-{T|zh:China;zh-tw:Taiwan}-! -This won't take interferes with the title rule-{H|zh:Beijing;zh-tw:Taipei}-. -!! result -Taiwan -

    This should be stripped! -This won't take interferes with the title rule. -

    -!! end - -!! test -Raw output of variant escape tags (R flag) -!! options -language=zh variant=zh-tw -!! input -Raw: -{R|zh:China;zh-tw:Taiwan}- -!! result -

    Raw: zh:China;zh-tw:Taiwan -

    -!! end - -!! test -Nested using of manual convert syntax -!! options -language=zh variant=zh-hk -!! input -Nested: -{zh-hans:Hi -{zh-cn:China;zh-sg:Singapore;}-;zh-hant:Hello -{zh-tw:Taiwan;zh-hk:H-{ong}- K-{}-ong;}-;}-! -!! result -

    Nested: Hello Hong Kong! -

    -!! end - -!! test -Do not convert roman numbers to language variants -!! options -language=sr variant=sr-ec -!! input -Fridrih IV je car. -!! result -

    Фридрих IV је цар. -

    -!! end - -!! test -Unclosed language converter markup "-{" -!! options -language=sr -!! input --{T|hello -!! result -

    -{T|hello -

    -!! end - -!! test -Don't convert raw rule "-{R|=>}-" to "=>" -!! options -language=sr -!! input --{R|=>}- -!! result -

    => -

    -!!end - -!!article -Template:Bullet -!!text -* Bar -!!endarticle - -!! test -Bug 529: Uncovered bullet -!! input -* Foo {{bullet}} -!! result -
    • Foo -
    • Bar -
    - -!! end - -!! test -Bug 529: Uncovered table already at line-start -!! input -x - -{{table}} -y -!! result -

    x -

    - - - - - - -
    1 2 -
    3 4 -
    -

    y -

    -!! end - -!! test -Bug 529: Uncovered bullet in parser function result -!! input -* Foo {{lc:{{bullet}} }} -!! result -
    • Foo -
    • bar -
    - -!! end - -!! test -Bug 5678: Double-parsed template argument -!! input -{{lc:{{{1}}}|hello}} -!! result -

    {{{1}}} -

    -!! end - -!! test -Bug 5678: Double-parsed template invocation -!! input -{{lc:{{paramtest {{!}} param = hello }} }} -!! result -

    {{paramtest | param = hello }} -

    -!! end - -!! test -Case insensitivity of parser functions for non-ASCII characters (bug 8143) -!! options -language=cs -title=[[Main Page]] -!! input -{{PRVNÍVELKÉ:ěščř}} -{{prvnívelké:ěščř}} -{{PRVNÍMALÉ:ěščř}} -{{prvnímalé:ěščř}} -{{MALÁ:ěščř}} -{{malá:ěščř}} -{{VELKÁ:ěščř}} -{{velká:ěščř}} -!! result -

    Ěščř -Ěščř -ěščř -ěščř -ěščř -ěščř -ĚŠČŘ -ĚŠČŘ -

    -!! end - -!! test -Morwen/13: Unclosed link followed by heading -!! input -[[link -==heading== -!! result -

    [[link -

    -

    [edit] heading

    - -!! end - -!! test -HHP2.1: Heuristics for headings in preprocessor parenthetical structures -!! input -{{foo| -=heading= -!! result -

    {{foo| -

    -

    heading

    - -!! end - -!! test -HHP2.2: Heuristics for headings in preprocessor parenthetical structures -!! input -{{foo| -==heading== -!! result -

    {{foo| -

    -

    [edit] heading

    - -!! end - -!! test -Tildes in comments -!! options -pst -!! input - -!! result - -!! end - -!! test -Paragraphs inside divs (no extra line breaks) -!! input -
    Line one - -Line two
    -!! result -
    Line one -Line two
    - -!! end - -!! test -Paragraphs inside divs (extra line break on open) -!! input -
    -Line one - -Line two
    -!! result -
    -

    Line one -

    -Line two
    - -!! end - -!! test -Paragraphs inside divs (extra line break on close) -!! input -
    Line one - -Line two -
    -!! result -
    Line one -

    Line two -

    -
    - -!! end - -!! test -Paragraphs inside divs (extra line break on open and close) -!! input -
    -Line one - -Line two -
    -!! result -
    -

    Line one -

    Line two -

    -
    - -!! end - -!! test -Nesting tags, paragraphs on lines which begin with
    -!! options -disabled -!! input -
    A -B -!! result -
    -

    A -B -

    -!! end - -# Bug 6200:
    should behave like
    with respect to line breaks -!! test -Bug 6200: paragraphs inside blockquotes (no extra line breaks) -!! options -disabled -!! input -
    Line one - -Line two
    -!! result -
    Line one -Line two
    - -!! end - -!! test -Bug 6200: paragraphs inside blockquotes (extra line break on open) -!! options -disabled -!! input -
    -Line one - -Line two
    -!! result -
    -

    Line one -

    -Line two
    - -!! end - -!! test -Bug 6200: paragraphs inside blockquotes (extra line break on close) -!! options -disabled -!! input -
    Line one - -Line two -
    -!! result -
    Line one -

    Line two -

    -
    - -!! end - -!! test -Bug 6200: paragraphs inside blockquotes (extra line break on open and close) -!! options -disabled -!! input -
    -Line one - -Line two -
    -!! result -
    -

    Line one -

    Line two -

    -
    - -!! end - -!! test -Paragraphs inside blockquotes/divs (no extra line breaks) -!! input -
    Line one - -Line two
    -!! result -
    Line one -Line two
    - -!! end - -!! test -Paragraphs inside blockquotes/divs (extra line break on open) -!! input -
    -Line one - -Line two
    -!! result -
    -

    Line one -

    -Line two
    - -!! end - -!! test -Paragraphs inside blockquotes/divs (extra line break on close) -!! input -
    Line one - -Line two -
    -!! result -
    Line one -

    Line two -

    -
    - -!! end - -!! test -Paragraphs inside blockquotes/divs (extra line break on open and close) -!! input -
    -Line one - -Line two -
    -!! result -
    -

    Line one -

    Line two -

    -
    - -!! end - -!! test -Interwiki links trounced by replaceExternalLinks after early LinkHolderArray expansion -!! options -wgLinkHolderBatchSize=0 -!! input -[[meatball:1]] -[[meatball:2]] -[[meatball:3]] -!! result -

    meatball:1 -meatball:2 -meatball:3 -

    -!! end - -!! test -Free external link invading image caption -!! input -[[Image:Foobar.jpg|thumb|http://x|hello]] -!! result -
    hello
    - -!! end - -!! test -Bug 15196: localised external link numbers -!! options -language=fa -!! input -[http://en.wikipedia.org/] -!! result -

    [۱] -

    -!! end - -!! test -Multibyte character in padleft -!! input -{{padleft:-Hello|7|Æ}} -!! result -

    Æ-Hello -

    -!! end - -!! test -Multibyte character in padright -!! input -{{padright:Hello-|7|Æ}} -!! result -

    Hello-Æ -

    -!! end - -!! test -Formatted date -!! config -wgUseDynamicDates=1 -!! input -[[2009-03-24]] -!! result -

    2009-03-24 -

    -!!end - -!!test -formatdate parser function -!!input -{{#formatdate:2009-03-24}} -!! result -

    2009-03-24 -

    -!! end - -!!test -formatdate parser function, with default format -!!input -{{#formatdate:2009-03-24|mdy}} -!! result -

    March 24, 2009 -

    -!! end - -!! test -Linked date with autoformatting disabled -!! config -wgUseDynamicDates=false -!! input -[[2009-03-24]] -!! result -

    2009-03-24 -

    -!! end - -!! test -Spacing of numbers in formatted dates -!! input -{{#formatdate:January 15}} -!! result -

    January 15 -

    -!! end - -!! test -Spacing of numbers in formatted dates (linked) -!! config -wgUseDynamicDates=true -!! input -[[January 15]] -!! result -

    January 15 -

    -!! end - -!! test -formatdate parser function, with default format and on a page of which the content language is always English and different from the wiki content language -!! options -language=nl title=[[MediaWiki:Common.css]] -!! input -{{#formatdate:2009-03-24|dmy}} -!! result -

    24 March 2009 -

    -!! end - -# -# -# - -# -# Edit comments -# - -!! test -Edit comment with link -!! options -comment -!! input -I like the [[Main Page]] a lot -!! result -I like the Main Page a lot -!!end - -!! test -Edit comment with link and link text -!! options -comment -!! input -I like the [[Main Page|best pages]] a lot -!! result -I like the best pages a lot -!!end - -!! test -Edit comment with link and link text with suffix -!! options -comment -!! input -I like the [[Main Page|best page]]s a lot -!! result -I like the best pages a lot -!!end - -!! test -Edit comment with section link (non-local, eg in history list) -!! options -comment title=[[Main Page]] -!! input -/* External links */ removed bogus entries -!! result -External links: removed bogus entries -!!end - -!! test -Edit comment with section link and text before it (non-local, eg in history list) -!! options -comment title=[[Main Page]] -!! input -pre-comment text /* External links */ removed bogus entries -!! result -pre-comment text - External links: removed bogus entries -!!end - -!! test -Edit comment with section link (local, eg in diff view) -!! options -comment local title=[[Main Page]] -!! input -/* External links */ removed bogus entries -!! result -External links: removed bogus entries -!!end - -!! test -Edit comment with subpage link (bug 14080) -!! options -comment -subpage -title=[[Subpage test]] -!! input -Poked at a [[/subpage]] here... -!! result -Poked at a /subpage here... -!!end - -!! test -Edit comment with subpage link and link text (bug 14080) -!! options -comment -subpage -title=[[Subpage test]] -!! input -Poked at a [[/subpage|neat little page]] here... -!! result -Poked at a neat little page here... -!!end - -!! test -Edit comment with bogus subpage link in non-subpage NS (bug 14080) -!! options -comment -title=[[Subpage test]] -!! input -Poked at a [[/subpage]] here... -!! result -Poked at a /subpage here... -!!end - -!! test -Edit comment with bare anchor link (local, as on diff) -!! options -comment -local -title=[[Main Page]] -!!input -[[#section]] -!! result -#section -!! end - -!! test -Edit comment with bare anchor link (non-local, as on history) -!! options -comment -title=[[Main Page]] -!!input -[[#section]] -!! result -#section -!! end - -!! test -Anchor starting with underscore -!!input -[[#_ref|One]] -!! result -

    One -

    -!! end - -!! test -Id starting with underscore -!!input -
    -!! result -
    - -!! end - -!! test -Space normalisation on autocomment (bug 22784) -!! options -comment -title=[[Main Page]] -!!input -/* __hello__world__ */ -!! result -__hello__world__ -!! end - -!! test -percent-encoding and + signs in comments (Bug 26410) -!! options -comment -!!input -[[ABC%33D% ++]] [[ABC%33D% ++|+%20]] -!! result -ABC3D% ++ +%20 -!! end - -!! test -Bad images - basic functionality -!! options -disabled -!! input -[[File:Bad.jpg]] -!! result -!! end - -!! test -Bad images - bug 16039: text after bad image disappears -!! options -disabled -!! input -Foo bar -[[File:Bad.jpg]] -Bar foo -!! result -

    Foo bar -

    Bar foo -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) no displaytitle -!! options -showtitle -!! config -wgAllowDisplayTitle=true -wgRestrictDisplayTitle=false -!! input -this is not the the title -!! result -Parser test -

    this is not the the title -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) RestrictDisplayTitle=false -!! options -showtitle -title=[[Screen]] -!! config -wgAllowDisplayTitle=true -wgRestrictDisplayTitle=false -!! input -this is not the the title -{{DISPLAYTITLE:whatever}} -!! result -whatever -

    this is not the the title -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) RestrictDisplayTitle=true mismatch -!! options -showtitle -title=[[Screen]] -!! config -wgAllowDisplayTitle=true -wgRestrictDisplayTitle=true -!! input -this is not the the title -{{DISPLAYTITLE:whatever}} -!! result -Screen -

    this is not the the title -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) RestrictDisplayTitle=true matching -!! options -showtitle -title=[[Screen]] -!! config -wgAllowDisplayTitle=true -wgRestrictDisplayTitle=true -!! input -this is not the the title -{{DISPLAYTITLE:screen}} -!! result -screen -

    this is not the the title -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) AllowDisplayTitle=false -!! options -showtitle -title=[[Screen]] -!! config -wgAllowDisplayTitle=false -!! input -this is not the the title -{{DISPLAYTITLE:screen}} -!! result -Screen -

    this is not the the title -Template:DISPLAYTITLE:screen -

    -!! end - -!! test -Verify that displaytitle works (bug #22501) AllowDisplayTitle=false no DISPLAYTITLE -!! options -showtitle -title=[[Screen]] -!! config -wgAllowDisplayTitle=false -!! input -this is not the the title -!! result -Screen -

    this is not the the title -

    -!! end - -!! test -preload: check and -!! options -preload -!! input -Hello cruelkind world. -!! result -Hello kind world. -!! end - -!! test -preload: check -!! options -preload -!! input -Goodbye Hello world -!! result -Hello world -!! end - -!! test -preload: can pass tags through if we want to -!! options -preload -!! input -<includeonly>Hello world</includeonly> -!! result -Hello world -!! end - -!! test -preload: check that it doesn't try to do tricks -!! options -preload -!! input -* ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}} -!! result -* ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}} -!! end - -!! test -Play a bit with r67090 and bug 3158 -!! options -disabled -!! input -
     
    -
     
    -
     
    -
     
    -!! result -
     
    -
     
    -
     
    -
     
    - -!! end - -!! test -HTML5 data attributes -!! input -Baz -

    Quuz

    -!! result -

    Baz -

    -

    Quuz

    - -!! end - -!! test -percent-encoding and + signs in internal links (Bug 26410) -!! input -[[User:+%]] [[Page+title%]] -[[%+]] [[%+|%20]] [[%+ ]] [[%+r]] -[[%]] [[+]] [[image:%+abc%39|foo|[[bar]]]] -[[%33%45]] [[%33%45+]] -!! result -

    User:+% Page+title% -%+ %20 %+ %+r -% + bar -3E 3E+ -

    -!! end - -!! test -Special characters in embedded file links (bug 27679) -!! input -[[File:Contains & ampersand.jpg]] -[[File:Does not exist.jpg|Title with & ampersand]] -!! result -

    File:Contains & ampersand.jpg -Title with & ampersand -

    -!! end - - -!! test -Confirm that 'apos' named character reference doesn't make it to output (not legal in HTML 4) -!! input -Text's been normalized? -!! result -

    Text's been normalized? -

    -!! end - -!! test -Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate free external links -!! input -http://www.example.org/ <-- U+3000 (vim: ^Vu3000) -!! result -

    http://www.example.org/ <-- U+3000 (vim: ^Vu3000) -

    -!! end - -!! test -Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate bracketed external links -!! input -[http://www.example.org/ ideograms] -!! result -

    ideograms -

    -!! end - -!! test -Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate external images links -!! input -http://www.example.org/pic.png <-- U+3000 (vim: ^Vu3000) -!! result -

    pic.png <-- U+3000 (vim: ^Vu3000) -

    -!! end - -!! article -Mediawiki:loop1 -!! text -{{Identical|A}} -!! endarticle - -!! article -Mediawiki:loop2 -!! text -{{Identical|B}} -!! endarticle - -!! article -Template:Identical -!! text -{{int:loop1}} -{{int:loop2}} -!! endarticle - -!! test -Bug 31098 Template which includes system messages which includes the template -!! input -{{Identical}} -!! result -

    Template loop detected: Template:Identical -Template loop detected: Template:Identical -

    -!! end - -!! test -Bug31490 Turkish: ucfirst 'blah' -!! options -language=tr -!! input -{{ucfirst:blah}} -!! result -

    Blah -

    -!! end - -!! test -Bug31490 Turkish: ucfirst 'ix' -!! options -language=tr -!! input -{{ucfirst:ix}} -!! result -

    İx -

    -!! end - -!! test -Bug31490 Turkish: lcfirst 'BLAH' -!! options -language=tr -!! input -{{lcfirst:BLAH}} -!! result -

    bLAH -

    -!! end - -!! test -Bug31490 Turkish: ucfırst (with a dotless i) -!! options -language=tr -!! input -{{ucfırst:blah}} -!! result -

    Şablon:Ucfırst:blah -

    -!! end - -!! test -Bug31490 ucfırst (with a dotless i) with English language -!! options -language=en -!! input -{{ucfırst:blah}} -!! result -

    Template:Ucfırst:blah -

    -!! end - -!! test -Bug 26375: TOC with italics -!! options -title=[[Main Page]] -!! input -__TOC__ -== ''Lost'' episodes == -!! result -

    Contents

    - -
    -

    [edit] Lost episodes

    - -!! end - -!! test -Bug 26375: TOC with bold -!! options -title=[[Main Page]] -!! input -__TOC__ -== '''should be bold''' then normal text == -!! result -

    Contents

    - -
    -

    [edit] should be bold then normal text

    - -!! end - -!! test -Bug 33845: Headings become cursive in TOC when they contain an image -!! options -title=[[Main Page]] -!! input -__TOC__ -== Image [[Image:foobar.jpg]] == -!! result -

    Contents

    - -
    -

    [edit] Image Foobar.jpg

    - -!! end - -!! test -Bug 33845 (2): Headings become bold in TOC when they contain a blockquote -!! options -title=[[Main Page]] -!! input -__TOC__ -==
    Quote
    == -!! result -

    Contents

    - -
    -

    [edit]
    Quote

    - -!! end - -!! test -Unclosed tags in TOC -!! options -title=[[Main Page]] -!! input -__TOC__ -== Proof: 2 < 3 == -Hanc marginis exiguitas non caperet. -QED -!! result -

    Contents

    - -
    -

    [edit] Proof: 2 < 3

    -

    Hanc marginis exiguitas non caperet. -QED -

    -!! end - -!! test -Multiple tags in TOC -!! input -__TOC__ -== Foo Bar == - -== Foo
    Bar
    == -!! result -

    Contents

    - -
    -

    [edit] Foo Bar

    -

    [edit] Foo
    Bar

    - -!! end - -!! test -Tags with parameters in TOC -!! input -__TOC__ -== Hello == - -== Evilbye == -!! result -

    Contents

    - -
    -

    [edit] Hello

    -

    [edit] b">Evilbye

    - -!! end - -!! article -MediaWiki:Bug32057 -!! text -== {{int:headline_sample}} == -!! endarticle - -!! test -Bug 32057: Title needed when expanding nodes. -!! options -title=[[Main Page]] -!! input -{{int:Bug32057}} -!! result -

    [edit] Headline text

    - -!! end - -!! test -Strip marker in urlencode -!! input -{{urlencode:xy}} -{{urlencode:xy|wiki}} -{{urlencode:xy|path}} -!! result -

    xy -xy -xy -

    -!! end - -!! test -Strip marker in lc -!! input -{{lc:xy}} -!! result -

    xy -

    -!! end - -!! test -Strip marker in uc -!! input -{{uc:xy}} -!! result -

    XY -

    -!! end - -!! test -Strip marker in formatNum -!! input -{{formatnum:12}} -{{formatnum:12|R}} -!! result -

    12 -12 -

    -!! end - -!! test -Strip marker in grammar -!! options -language=fi -!! input -{{grammar:elative|foobar}} -!! result -

    foobarista -

    -!! end - -!! test -Strip marker in padleft -!! input -{{padleft:|2|xy}} -!! result -

    xy -

    -!! end - -!! test -Strip marker in padright -!! input -{{padright:|2|xy}} -!! result -

    xy -

    -!! end - -!! test -Strip marker in anchorencode -!! input -{{anchorencode:xy}} -!! result -

    xy -

    -!! end - -!! test -nowiki inside link inside heading (bug 18295) -!! input -==[[foo|xyz]]== -!! result -

    [edit] xyz

    - -!! end - -!! test -new support for bdi element (bug 31817) -!! input -

    ולדימיר לנין (ברוסית: Владимир Ленин, 24 באפריל 1870–22 בינואר 1924) הוא מנהיג פוליטי קומוניסטי רוסי.

    -!! result -

    ולדימיר לנין (ברוסית: Владимир Ленин, 24 באפריל 1870–22 בינואר 1924) הוא מנהיג פוליטי קומוניסטי רוסי.

    - -!!end - -!! test -Ignore pipe between table row attributes -!! input -{| -| quux -|- id=foo | style='color: red' -| bar -|} -!! result - - - - -
    quux -
    bar -
    - -!! end - -!!test -Gallery override link with WikiLink (bug 34852) -!! input - -File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink - -!! result - - -!! end - -!!test -Gallery override link with absolute external link (bug 34852) -!! input - -File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org - -!! result - - -!! end - -!!test -Gallery override link with malicious javascript (bug 34852) -!! input - -File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascript code!'); - -!! result - - -!! end - -!!test -Language parser function -!! input -{{#language:ar}} -!! result -

    العربية -

    -!! end - -!!test -Padleft and padright as substr -!! input -{{padleft:|3|abcde}} -{{padright:|3|abcde}} -!! result -

    abc -abc -

    -!! end - -!!test -Bug 34939 - Case insensitive link parsing ([HttP://]) -!! input -[HttP://MediaWiki.Org/] -!! result -

    [1] -

    -!! end - -!!test -Bug 34939 - Case insensitive link parsing ([HttP:// title]) -!! input -[HttP://MediaWiki.Org/ MediaWiki] -!! result -

    MediaWiki -

    -!! end - -!!test -Bug 34939 - Case insensitive link parsing (HttP://) -!! input -HttP://MediaWiki.Org/ -!! result -

    HttP://MediaWiki.Org/ -

    -!! end - - -TODO: -more images -more tables -character entities -and much more -Try for 100% code coverage diff --git a/tests/parser/parserTestsParserHook.php b/tests/parser/parserTestsParserHook.php deleted file mode 100644 index 24d852c5..00000000 --- a/tests/parser/parserTestsParserHook.php +++ /dev/null @@ -1,70 +0,0 @@ - - */ - -class ParserTestParserHook { - - static function setup( &$parser ) { - $parser->setHook( 'tag', array( __CLASS__, 'dumpHook' ) ); - $parser->setHook( 'statictag', array( __CLASS__, 'staticTagHook' ) ); - return true; - } - - static function dumpHook( $in, $argv ) { - ob_start(); - var_dump( - $in, - $argv - ); - $ret = ob_get_clean(); - - return "
    \n$ret
    "; - } - - static function staticTagHook( $in, $argv, $parser ) { - if ( ! count( $argv ) ) { - $parser->static_tag_buf = $in; - return ''; - } elseif ( count( $argv ) === 1 && isset( $argv['action'] ) - && $argv['action'] === 'flush' && $in === null ) - { - // Clear the buffer, we probably don't need to - if ( isset( $parser->static_tag_buf ) ) { - $tmp = $parser->static_tag_buf; - } else { - $tmp = ''; - } - $parser->static_tag_buf = null; - return $tmp; - } else - // wtf? - return - "\nCall this extension as string or as" . - " , not in any other way.\n" . - "text: " . var_export( $in, true ) . "\n" . - "argv: " . var_export( $argv, true ) . "\n"; - } -} diff --git a/tests/parser/preprocess/All_system_messages.expected b/tests/parser/preprocess/All_system_messages.expected deleted file mode 100644 index 897c5fb0..00000000 --- a/tests/parser/preprocess/All_system_messages.expected +++ /dev/null @@ -1,5646 +0,0 @@ - - -<table border=1 width=100%><tr><td> -'''Name''' -</td><td> -'''Default text''' -</td><td> -'''Current text''' -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:1movedto2&action=edit 1movedto2]<br> -[[MediaWiki_talk:1movedto2|Talk]] -</td><td> -$1 moved to $2 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Monobook.css&action=edit Monobook.css]<br> -[[MediaWiki_talk:Monobook.css|Talk]] -</td><td> -/* edit this file to customize the monobook skin for the entire site */ -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:About&action=edit about]<br> -[[MediaWiki_talk:About|Talk]] -</td><td> -About -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Aboutpage&action=edit aboutpage]<br> -[[MediaWiki_talk:Aboutpage|Talk]] -</td><td> -Wiktionary:About -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Aboutwikipedia&action=edit aboutwikipedia]<br> -[[MediaWiki_talk:Aboutwikipedia|Talk]] -</td><td> -About Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-addsection&action=edit accesskey-addsection]<br> -[[MediaWiki_talk:Accesskey-addsection|Talk]] -</td><td> -+ -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-anontalk&action=edit accesskey-anontalk]<br> -[[MediaWiki_talk:Accesskey-anontalk|Talk]] -</td><td> -n -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-anonuserpage&action=edit accesskey-anonuserpage]<br> -[[MediaWiki_talk:Accesskey-anonuserpage|Talk]] -</td><td> -. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-article&action=edit accesskey-article]<br> -[[MediaWiki_talk:Accesskey-article|Talk]] -</td><td> -a -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-compareselectedversions&action=edit accesskey-compareselectedversions]<br> -[[MediaWiki_talk:Accesskey-compareselectedversions|Talk]] -</td><td> -v -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-contributions&action=edit accesskey-contributions]<br> -[[MediaWiki_talk:Accesskey-contributions|Talk]] -</td><td> -&amp;lt;accesskey-contributions&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-currentevents&action=edit accesskey-currentevents]<br> -[[MediaWiki_talk:Accesskey-currentevents|Talk]] -</td><td> -&amp;lt;accesskey-currentevents&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-delete&action=edit accesskey-delete]<br> -[[MediaWiki_talk:Accesskey-delete|Talk]] -</td><td> -d -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-edit&action=edit accesskey-edit]<br> -[[MediaWiki_talk:Accesskey-edit|Talk]] -</td><td> -e -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-emailuser&action=edit accesskey-emailuser]<br> -[[MediaWiki_talk:Accesskey-emailuser|Talk]] -</td><td> -&amp;lt;accesskey-emailuser&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-help&action=edit accesskey-help]<br> -[[MediaWiki_talk:Accesskey-help|Talk]] -</td><td> -&amp;lt;accesskey-help&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-history&action=edit accesskey-history]<br> -[[MediaWiki_talk:Accesskey-history|Talk]] -</td><td> -h -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-login&action=edit accesskey-login]<br> -[[MediaWiki_talk:Accesskey-login|Talk]] -</td><td> -o -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-logout&action=edit accesskey-logout]<br> -[[MediaWiki_talk:Accesskey-logout|Talk]] -</td><td> -o -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mainpage&action=edit accesskey-mainpage]<br> -[[MediaWiki_talk:Accesskey-mainpage|Talk]] -</td><td> -z -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-minoredit&action=edit accesskey-minoredit]<br> -[[MediaWiki_talk:Accesskey-minoredit|Talk]] -</td><td> -i -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-move&action=edit accesskey-move]<br> -[[MediaWiki_talk:Accesskey-move|Talk]] -</td><td> -m -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mycontris&action=edit accesskey-mycontris]<br> -[[MediaWiki_talk:Accesskey-mycontris|Talk]] -</td><td> -y -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mytalk&action=edit accesskey-mytalk]<br> -[[MediaWiki_talk:Accesskey-mytalk|Talk]] -</td><td> -n -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-portal&action=edit accesskey-portal]<br> -[[MediaWiki_talk:Accesskey-portal|Talk]] -</td><td> -&amp;lt;accesskey-portal&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-preferences&action=edit accesskey-preferences]<br> -[[MediaWiki_talk:Accesskey-preferences|Talk]] -</td><td> -&amp;lt;accesskey-preferences&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-preview&action=edit accesskey-preview]<br> -[[MediaWiki_talk:Accesskey-preview|Talk]] -</td><td> -p -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-protect&action=edit accesskey-protect]<br> -[[MediaWiki_talk:Accesskey-protect|Talk]] -</td><td> -= -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-randompage&action=edit accesskey-randompage]<br> -[[MediaWiki_talk:Accesskey-randompage|Talk]] -</td><td> -x -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-recentchanges&action=edit accesskey-recentchanges]<br> -[[MediaWiki_talk:Accesskey-recentchanges|Talk]] -</td><td> -r -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-recentchangeslinked&action=edit accesskey-recentchangeslinked]<br> -[[MediaWiki_talk:Accesskey-recentchangeslinked|Talk]] -</td><td> -c -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-save&action=edit accesskey-save]<br> -[[MediaWiki_talk:Accesskey-save|Talk]] -</td><td> -s -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-search&action=edit accesskey-search]<br> -[[MediaWiki_talk:Accesskey-search|Talk]] -</td><td> -f -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-sitesupport&action=edit accesskey-sitesupport]<br> -[[MediaWiki_talk:Accesskey-sitesupport|Talk]] -</td><td> -&amp;lt;accesskey-sitesupport&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-specialpage&action=edit accesskey-specialpage]<br> -[[MediaWiki_talk:Accesskey-specialpage|Talk]] -</td><td> -&amp;lt;accesskey-specialpage&amp;gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-specialpages&action=edit accesskey-specialpages]<br> -[[MediaWiki_talk:Accesskey-specialpages|Talk]] -</td><td> -q -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-talk&action=edit accesskey-talk]<br> -[[MediaWiki_talk:Accesskey-talk|Talk]] -</td><td> -t -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-undelete&action=edit accesskey-undelete]<br> -[[MediaWiki_talk:Accesskey-undelete|Talk]] -</td><td> -d -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-unwatch&action=edit accesskey-unwatch]<br> -[[MediaWiki_talk:Accesskey-unwatch|Talk]] -</td><td> -w -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-upload&action=edit accesskey-upload]<br> -[[MediaWiki_talk:Accesskey-upload|Talk]] -</td><td> -u -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-userpage&action=edit accesskey-userpage]<br> -[[MediaWiki_talk:Accesskey-userpage|Talk]] -</td><td> -. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-viewsource&action=edit accesskey-viewsource]<br> -[[MediaWiki_talk:Accesskey-viewsource|Talk]] -</td><td> -e -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-watch&action=edit accesskey-watch]<br> -[[MediaWiki_talk:Accesskey-watch|Talk]] -</td><td> -w -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-watchlist&action=edit accesskey-watchlist]<br> -[[MediaWiki_talk:Accesskey-watchlist|Talk]] -</td><td> -l -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-whatlinkshere&action=edit accesskey-whatlinkshere]<br> -[[MediaWiki_talk:Accesskey-whatlinkshere|Talk]] -</td><td> -b -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accmailtext&action=edit accmailtext]<br> -[[MediaWiki_talk:Accmailtext|Talk]] -</td><td> -The Password for &#39;$1&#39; has been sent to $2. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accmailtitle&action=edit accmailtitle]<br> -[[MediaWiki_talk:Accmailtitle|Talk]] -</td><td> -Password sent. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Actioncomplete&action=edit actioncomplete]<br> -[[MediaWiki_talk:Actioncomplete|Talk]] -</td><td> -Action complete -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addedwatch&action=edit addedwatch]<br> -[[MediaWiki_talk:Addedwatch|Talk]] -</td><td> -Added to watchlist -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addedwatchtext&action=edit addedwatchtext]<br> -[[MediaWiki_talk:Addedwatchtext|Talk]] -</td><td> -The page &quot;$1&quot; has been added to your &#91;&#91;Special:Watchlist&#124;watchlist]]. -Future changes to this page and its associated Talk page will be listed there, -and the page will appear &#39;&#39;&#39;bolded&#39;&#39;&#39; in the &#91;&#91;Special:Recentchanges&#124;list of recent changes]] to -make it easier to pick out. - -&lt;p&gt;If you want to remove the page from your watchlist later, click &quot;Stop watching&quot; in the sidebar. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addsection&action=edit addsection]<br> -[[MediaWiki_talk:Addsection|Talk]] -</td><td> -+ -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Administrators&action=edit administrators]<br> -[[MediaWiki_talk:Administrators|Talk]] -</td><td> -Wiktionary:Administrators -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Affirmation&action=edit affirmation]<br> -[[MediaWiki_talk:Affirmation|Talk]] -</td><td> -I affirm that the copyright holder of this file -agrees to license it under the terms of the $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:All&action=edit all]<br> -[[MediaWiki_talk:All|Talk]] -</td><td> -all -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allmessages&action=edit allmessages]<br> -[[MediaWiki_talk:Allmessages|Talk]] -</td><td> -All system messages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allmessagestext&action=edit allmessagestext]<br> -[[MediaWiki_talk:Allmessagestext|Talk]] -</td><td> -This is a list of all system messages available in the MediaWiki: namespace. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allpages&action=edit allpages]<br> -[[MediaWiki_talk:Allpages|Talk]] -</td><td> -All pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alphaindexline&action=edit alphaindexline]<br> -[[MediaWiki_talk:Alphaindexline|Talk]] -</td><td> -$1 to $2 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alreadyloggedin&action=edit alreadyloggedin]<br> -[[MediaWiki_talk:Alreadyloggedin|Talk]] -</td><td> -&lt;font color=red&gt;&lt;b&gt;User $1, you are already logged in!&lt;/b&gt;&lt;/font&gt;&lt;br /&gt; - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alreadyrolled&action=edit alreadyrolled]<br> -[[MediaWiki_talk:Alreadyrolled|Talk]] -</td><td> -Cannot rollback last edit of &#91;&#91;$1]] -by &#91;&#91;User:$2&#124;$2]] (&#91;&#91;User talk:$2&#124;Talk]]); someone else has edited or rolled back the page already. - -Last edit was by &#91;&#91;User:$3&#124;$3]] (&#91;&#91;User talk:$3&#124;Talk]]). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ancientpages&action=edit ancientpages]<br> -[[MediaWiki_talk:Ancientpages|Talk]] -</td><td> -Oldest pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:And&action=edit and]<br> -[[MediaWiki_talk:And|Talk]] -</td><td> -and -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anontalk&action=edit anontalk]<br> -[[MediaWiki_talk:Anontalk|Talk]] -</td><td> -Talk for this IP -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anontalkpagetext&action=edit anontalkpagetext]<br> -[[MediaWiki_talk:Anontalkpagetext|Talk]] -</td><td> -----&#39;&#39;This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical &#91;&#91;IP address]] to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please &#91;&#91;Special:Userlogin&#124;create an account or log in]] to avoid future confusion with other anonymous users.&#39;&#39; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anonymous&action=edit anonymous]<br> -[[MediaWiki_talk:Anonymous|Talk]] -</td><td> -Anonymous user(s) of Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Article&action=edit article]<br> -[[MediaWiki_talk:Article|Talk]] -</td><td> -Content page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Articleexists&action=edit articleexists]<br> -[[MediaWiki_talk:Articleexists|Talk]] -</td><td> -A page of that name already exists, or the -name you have chosen is not valid. -Please choose another name. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Articlepage&action=edit articlepage]<br> -[[MediaWiki_talk:Articlepage|Talk]] -</td><td> -View content page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Asksql&action=edit asksql]<br> -[[MediaWiki_talk:Asksql|Talk]] -</td><td> -SQL query -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Asksqltext&action=edit asksqltext]<br> -[[MediaWiki_talk:Asksqltext|Talk]] -</td><td> -Use the form below to make a direct query of the -database. -Use single quotes (&#39;like this&#39;) to delimit string literals. -This can often add considerable load to the server, so please use -this function sparingly. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Autoblocker&action=edit autoblocker]<br> -[[MediaWiki_talk:Autoblocker|Talk]] -</td><td> -Autoblocked because you share an IP address with &quot;$1&quot;. Reason &quot;$2&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badarticleerror&action=edit badarticleerror]<br> -[[MediaWiki_talk:Badarticleerror|Talk]] -</td><td> -This action cannot be performed on this page. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badfilename&action=edit badfilename]<br> -[[MediaWiki_talk:Badfilename|Talk]] -</td><td> -Image name has been changed to &quot;$1&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badfiletype&action=edit badfiletype]<br> -[[MediaWiki_talk:Badfiletype|Talk]] -</td><td> -&quot;.$1&quot; is not a recommended image file format. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badipaddress&action=edit badipaddress]<br> -[[MediaWiki_talk:Badipaddress|Talk]] -</td><td> -Invalid IP address -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badquery&action=edit badquery]<br> -[[MediaWiki_talk:Badquery|Talk]] -</td><td> -Badly formed search query -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badquerytext&action=edit badquerytext]<br> -[[MediaWiki_talk:Badquerytext|Talk]] -</td><td> -We could not process your query. -This is probably because you have attempted to search for a -word fewer than three letters long, which is not yet supported. -It could also be that you have mistyped the expression, for -example &quot;fish and and scales&quot;. -Please try another query. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badretype&action=edit badretype]<br> -[[MediaWiki_talk:Badretype|Talk]] -</td><td> -The passwords you entered do not match. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badtitle&action=edit badtitle]<br> -[[MediaWiki_talk:Badtitle|Talk]] -</td><td> -Bad title -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badtitletext&action=edit badtitletext]<br> -[[MediaWiki_talk:Badtitletext|Talk]] -</td><td> -The requested page title was invalid, empty, or -an incorrectly linked inter-language or inter-wiki title. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blanknamespace&action=edit blanknamespace]<br> -[[MediaWiki_talk:Blanknamespace|Talk]] -</td><td> -(Main) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockedtext&action=edit blockedtext]<br> -[[MediaWiki_talk:Blockedtext|Talk]] -</td><td> -Your user name or IP address has been blocked by $1. -The reason given is this:&lt;br /&gt;&#39;&#39;$2&#39;&#39;&lt;p&gt;You may contact $1 or one of the other -&#91;&#91;Wiktionary:Administrators&#124;administrators]] to discuss the block. - -Note that you may not use the &quot;email this user&quot; feature unless you have a valid email address registered in your &#91;&#91;Special:Preferences&#124;user preferences]]. - -Your IP address is $3. Please include this address in any queries you make. - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockedtitle&action=edit blockedtitle]<br> -[[MediaWiki_talk:Blockedtitle|Talk]] -</td><td> -User is blocked -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockip&action=edit blockip]<br> -[[MediaWiki_talk:Blockip|Talk]] -</td><td> -Block user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockipsuccesssub&action=edit blockipsuccesssub]<br> -[[MediaWiki_talk:Blockipsuccesssub|Talk]] -</td><td> -Block succeeded -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockipsuccesstext&action=edit blockipsuccesstext]<br> -[[MediaWiki_talk:Blockipsuccesstext|Talk]] -</td><td> -&quot;$1&quot; has been blocked. -&lt;br /&gt;See &#91;&#91;Special:Ipblocklist&#124;IP block list]] to review blocks. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockiptext&action=edit blockiptext]<br> -[[MediaWiki_talk:Blockiptext|Talk]] -</td><td> -Use the form below to block write access -from a specific IP address or username. -This should be done only only to prevent vandalism, and in -accordance with &#91;&#91;Wiktionary:Policy&#124;policy]]. -Fill in a specific reason below (for example, citing particular -pages that were vandalized). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklink&action=edit blocklink]<br> -[[MediaWiki_talk:Blocklink|Talk]] -</td><td> -block -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklistline&action=edit blocklistline]<br> -[[MediaWiki_talk:Blocklistline|Talk]] -</td><td> -$1, $2 blocked $3 (expires $4) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogentry&action=edit blocklogentry]<br> -[[MediaWiki_talk:Blocklogentry|Talk]] -</td><td> -blocked &quot;$1&quot; with an expiry time of $2 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogpage&action=edit blocklogpage]<br> -[[MediaWiki_talk:Blocklogpage|Talk]] -</td><td> -Block_log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogtext&action=edit blocklogtext]<br> -[[MediaWiki_talk:Blocklogtext|Talk]] -</td><td> -This is a log of user blocking and unblocking actions. Automatically -blocked IP addresses are not be listed. See the &#91;&#91;Special:Ipblocklist&#124;IP block list]] for -the list of currently operational bans and blocks. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bold_sample&action=edit bold_sample]<br> -[[MediaWiki_talk:Bold_sample|Talk]] -</td><td> -Bold text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bold_tip&action=edit bold_tip]<br> -[[MediaWiki_talk:Bold_tip|Talk]] -</td><td> -Bold text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Booksources&action=edit booksources]<br> -[[MediaWiki_talk:Booksources|Talk]] -</td><td> -Book sources -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Booksourcetext&action=edit booksourcetext]<br> -[[MediaWiki_talk:Booksourcetext|Talk]] -</td><td> -Below is a list of links to other sites that -sell new and used books, and may also have further information -about books you are looking for.Wiktionary is not affiliated with any of these businesses, and -this list should not be construed as an endorsement. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Brokenredirects&action=edit brokenredirects]<br> -[[MediaWiki_talk:Brokenredirects|Talk]] -</td><td> -Broken Redirects -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Brokenredirectstext&action=edit brokenredirectstext]<br> -[[MediaWiki_talk:Brokenredirectstext|Talk]] -</td><td> -The following redirects link to a non-existing pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bugreports&action=edit bugreports]<br> -[[MediaWiki_talk:Bugreports|Talk]] -</td><td> -Bug reports -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bugreportspage&action=edit bugreportspage]<br> -[[MediaWiki_talk:Bugreportspage|Talk]] -</td><td> -Wiktionary:Bug_reports -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucratlog&action=edit bureaucratlog]<br> -[[MediaWiki_talk:Bureaucratlog|Talk]] -</td><td> -Bureaucrat_log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucratlogentry&action=edit bureaucratlogentry]<br> -[[MediaWiki_talk:Bureaucratlogentry|Talk]] -</td><td> -Rights for user &quot;$1&quot; set &quot;$2&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucrattext&action=edit bureaucrattext]<br> -[[MediaWiki_talk:Bureaucrattext|Talk]] -</td><td> -The action you have requested can only be -performed by sysops with &quot;bureaucrat&quot; status. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucrattitle&action=edit bureaucrattitle]<br> -[[MediaWiki_talk:Bureaucrattitle|Talk]] -</td><td> -Bureaucrat access required -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bydate&action=edit bydate]<br> -[[MediaWiki_talk:Bydate|Talk]] -</td><td> -by date -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Byname&action=edit byname]<br> -[[MediaWiki_talk:Byname|Talk]] -</td><td> -by name -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bysize&action=edit bysize]<br> -[[MediaWiki_talk:Bysize|Talk]] -</td><td> -by size -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cachederror&action=edit cachederror]<br> -[[MediaWiki_talk:Cachederror|Talk]] -</td><td> -The following is a cached copy of the requested page, and may not be up to date. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cancel&action=edit cancel]<br> -[[MediaWiki_talk:Cancel|Talk]] -</td><td> -Cancel -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cannotdelete&action=edit cannotdelete]<br> -[[MediaWiki_talk:Cannotdelete|Talk]] -</td><td> -Could not delete the page or image specified. (It may have already been deleted by someone else.) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cantrollback&action=edit cantrollback]<br> -[[MediaWiki_talk:Cantrollback|Talk]] -</td><td> -Cannot revert edit; last contributor is only author of this page. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Categories&action=edit categories]<br> -[[MediaWiki_talk:Categories|Talk]] -</td><td> -Categories -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Category&action=edit category]<br> -[[MediaWiki_talk:Category|Talk]] -</td><td> -category -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Category_header&action=edit category_header]<br> -[[MediaWiki_talk:Category_header|Talk]] -</td><td> -Articles in category &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Changepassword&action=edit changepassword]<br> -[[MediaWiki_talk:Changepassword|Talk]] -</td><td> -Change password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Changes&action=edit changes]<br> -[[MediaWiki_talk:Changes|Talk]] -</td><td> -changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Columns&action=edit columns]<br> -[[MediaWiki_talk:Columns|Talk]] -</td><td> -Columns -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Commentedit&action=edit commentedit]<br> -[[MediaWiki_talk:Commentedit|Talk]] -</td><td> - (comment) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Compareselectedversions&action=edit compareselectedversions]<br> -[[MediaWiki_talk:Compareselectedversions|Talk]] -</td><td> -Compare selected versions -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirm&action=edit confirm]<br> -[[MediaWiki_talk:Confirm|Talk]] -</td><td> -Confirm -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmcheck&action=edit confirmcheck]<br> -[[MediaWiki_talk:Confirmcheck|Talk]] -</td><td> -Yes, I really want to delete this. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmdelete&action=edit confirmdelete]<br> -[[MediaWiki_talk:Confirmdelete|Talk]] -</td><td> -Confirm delete -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmdeletetext&action=edit confirmdeletetext]<br> -[[MediaWiki_talk:Confirmdeletetext|Talk]] -</td><td> -You are about to permanently delete a page -or image along with all of its history from the database. -Please confirm that you intend to do this, that you understand the -consequences, and that you are doing this in accordance with -&#91;&#91;Wiktionary:Policy]]. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmprotect&action=edit confirmprotect]<br> -[[MediaWiki_talk:Confirmprotect|Talk]] -</td><td> -Confirm protection -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmprotecttext&action=edit confirmprotecttext]<br> -[[MediaWiki_talk:Confirmprotecttext|Talk]] -</td><td> -Do you really want to protect this page? -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmunprotect&action=edit confirmunprotect]<br> -[[MediaWiki_talk:Confirmunprotect|Talk]] -</td><td> -Confirm unprotection -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmunprotecttext&action=edit confirmunprotecttext]<br> -[[MediaWiki_talk:Confirmunprotecttext|Talk]] -</td><td> -Do you really want to unprotect this page? -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contextchars&action=edit contextchars]<br> -[[MediaWiki_talk:Contextchars|Talk]] -</td><td> -Characters of context per line -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contextlines&action=edit contextlines]<br> -[[MediaWiki_talk:Contextlines|Talk]] -</td><td> -Lines to show per hit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contribslink&action=edit contribslink]<br> -[[MediaWiki_talk:Contribslink|Talk]] -</td><td> -contribs -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contribsub&action=edit contribsub]<br> -[[MediaWiki_talk:Contribsub|Talk]] -</td><td> -For $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contributions&action=edit contributions]<br> -[[MediaWiki_talk:Contributions|Talk]] -</td><td> -User contributions -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyright&action=edit copyright]<br> -[[MediaWiki_talk:Copyright|Talk]] -</td><td> -Content is available under $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightpage&action=edit copyrightpage]<br> -[[MediaWiki_talk:Copyrightpage|Talk]] -</td><td> -Wiktionary:Copyrights -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightpagename&action=edit copyrightpagename]<br> -[[MediaWiki_talk:Copyrightpagename|Talk]] -</td><td> -Wiktionary copyright -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightwarning&action=edit copyrightwarning]<br> -[[MediaWiki_talk:Copyrightwarning|Talk]] -</td><td> -Please note that all contributions to Wiktionary are -considered to be released under the GNU Free Documentation License -(see $1 for details). -If you don&#39;t want your writing to be edited mercilessly and redistributed -at will, then don&#39;t submit it here.&lt;br /&gt; -You are also promising us that you wrote this yourself, or copied it from a -public domain or similar free resource. -&lt;strong&gt;DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!&lt;/strong&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Couldntremove&action=edit couldntremove]<br> -[[MediaWiki_talk:Couldntremove|Talk]] -</td><td> -Couldn&#39;t remove item &#39;$1&#39;... -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Createaccount&action=edit createaccount]<br> -[[MediaWiki_talk:Createaccount|Talk]] -</td><td> -Create new account -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Createaccountmail&action=edit createaccountmail]<br> -[[MediaWiki_talk:Createaccountmail|Talk]] -</td><td> -by email -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cur&action=edit cur]<br> -[[MediaWiki_talk:Cur|Talk]] -</td><td> -cur -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Currentevents&action=edit currentevents]<br> -[[MediaWiki_talk:Currentevents|Talk]] -</td><td> -Current events -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Currentrev&action=edit currentrev]<br> -[[MediaWiki_talk:Currentrev|Talk]] -</td><td> -Current revision -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Databaseerror&action=edit databaseerror]<br> -[[MediaWiki_talk:Databaseerror|Talk]] -</td><td> -Database error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dateformat&action=edit dateformat]<br> -[[MediaWiki_talk:Dateformat|Talk]] -</td><td> -Date format -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dberrortext&action=edit dberrortext]<br> -[[MediaWiki_talk:Dberrortext|Talk]] -</td><td> -A database query syntax error has occurred. -This could be because of an illegal search query (see $5), -or it may indicate a bug in the software. -The last attempted database query was: -&lt;blockquote&gt;&lt;tt&gt;$1&lt;/tt&gt;&lt;/blockquote&gt; -from within function &quot;&lt;tt&gt;$2&lt;/tt&gt;&quot;. -MySQL returned error &quot;&lt;tt&gt;$3: $4&lt;/tt&gt;&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dberrortextcl&action=edit dberrortextcl]<br> -[[MediaWiki_talk:Dberrortextcl|Talk]] -</td><td> -A database query syntax error has occurred. -The last attempted database query was: -&quot;$1&quot; -from within function &quot;$2&quot;. -MySQL returned error &quot;$3: $4&quot;. - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deadendpages&action=edit deadendpages]<br> -[[MediaWiki_talk:Deadendpages|Talk]] -</td><td> -Dead-end pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Debug&action=edit debug]<br> -[[MediaWiki_talk:Debug|Talk]] -</td><td> -Debug -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Defaultns&action=edit defaultns]<br> -[[MediaWiki_talk:Defaultns|Talk]] -</td><td> -Search in these namespaces by default: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Defemailsubject&action=edit defemailsubject]<br> -[[MediaWiki_talk:Defemailsubject|Talk]] -</td><td> -Wiktionary e-mail -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Delete&action=edit delete]<br> -[[MediaWiki_talk:Delete|Talk]] -</td><td> -Delete -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletecomment&action=edit deletecomment]<br> -[[MediaWiki_talk:Deletecomment|Talk]] -</td><td> -Reason for deletion -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletedarticle&action=edit deletedarticle]<br> -[[MediaWiki_talk:Deletedarticle|Talk]] -</td><td> -deleted &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletedtext&action=edit deletedtext]<br> -[[MediaWiki_talk:Deletedtext|Talk]] -</td><td> -&quot;$1&quot; has been deleted. -See $2 for a record of recent deletions. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deleteimg&action=edit deleteimg]<br> -[[MediaWiki_talk:Deleteimg|Talk]] -</td><td> -del -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletepage&action=edit deletepage]<br> -[[MediaWiki_talk:Deletepage|Talk]] -</td><td> -Delete page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletesub&action=edit deletesub]<br> -[[MediaWiki_talk:Deletesub|Talk]] -</td><td> -(Deleting &quot;$1&quot;) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletethispage&action=edit deletethispage]<br> -[[MediaWiki_talk:Deletethispage|Talk]] -</td><td> -Delete this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletionlog&action=edit deletionlog]<br> -[[MediaWiki_talk:Deletionlog|Talk]] -</td><td> -deletion log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dellogpage&action=edit dellogpage]<br> -[[MediaWiki_talk:Dellogpage|Talk]] -</td><td> -Deletion_log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dellogpagetext&action=edit dellogpagetext]<br> -[[MediaWiki_talk:Dellogpagetext|Talk]] -</td><td> -Below is a list of the most recent deletions. -All times shown are server time (UTC). -&lt;ul&gt; -&lt;/ul&gt; - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developerspheading&action=edit developerspheading]<br> -[[MediaWiki_talk:Developerspheading|Talk]] -</td><td> -For developer use only -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developertext&action=edit developertext]<br> -[[MediaWiki_talk:Developertext|Talk]] -</td><td> -The action you have requested can only be -performed by users with &quot;developer&quot; status. -See $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developertitle&action=edit developertitle]<br> -[[MediaWiki_talk:Developertitle|Talk]] -</td><td> -Developer access required -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Diff&action=edit diff]<br> -[[MediaWiki_talk:Diff|Talk]] -</td><td> -diff -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Difference&action=edit difference]<br> -[[MediaWiki_talk:Difference|Talk]] -</td><td> -(Difference between revisions) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguations&action=edit disambiguations]<br> -[[MediaWiki_talk:Disambiguations|Talk]] -</td><td> -Disambiguation pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationspage&action=edit disambiguationspage]<br> -[[MediaWiki_talk:Disambiguationspage|Talk]] -</td><td> -Wiktionary:Links_to_disambiguating_pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationstext&action=edit disambiguationstext]<br> -[[MediaWiki_talk:Disambiguationstext|Talk]] -</td><td> -The following pages link to a &lt;i&gt;disambiguation page&lt;/i&gt;. They should link to the appropriate topic instead.&lt;br /&gt;A page is treated as dismbiguation if it is linked from $1.&lt;br /&gt;Links from other namespaces are &lt;i&gt;not&lt;/i&gt; listed here. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]<br> -[[MediaWiki_talk:Disclaimerpage|Talk]] -</td><td> -Wiktionary:General_disclaimer -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimers&action=edit disclaimers]<br> -[[MediaWiki_talk:Disclaimers|Talk]] -</td><td> -Disclaimers -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Doubleredirects&action=edit doubleredirects]<br> -[[MediaWiki_talk:Doubleredirects|Talk]] -</td><td> -Double Redirects -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Doubleredirectstext&action=edit doubleredirectstext]<br> -[[MediaWiki_talk:Doubleredirectstext|Talk]] -</td><td> -&lt;b&gt;Attention:&lt;/b&gt; This list may contain false positives. That usually means there is additional text with links below the first #REDIRECT.&lt;br /&gt; -Each row contains links to the first and second redirect, as well as the first line of the second redirect text, usually giving the &quot;real&quot; target page, which the first redirect should point to. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edit&action=edit edit]<br> -[[MediaWiki_talk:Edit|Talk]] -</td><td> -Edit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editcomment&action=edit editcomment]<br> -[[MediaWiki_talk:Editcomment|Talk]] -</td><td> -The edit comment was: &quot;&lt;i&gt;$1&lt;/i&gt;&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editconflict&action=edit editconflict]<br> -[[MediaWiki_talk:Editconflict|Talk]] -</td><td> -Edit conflict: $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editcurrent&action=edit editcurrent]<br> -[[MediaWiki_talk:Editcurrent|Talk]] -</td><td> -Edit the current version of this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edithelp&action=edit edithelp]<br> -[[MediaWiki_talk:Edithelp|Talk]] -</td><td> -Editing help -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edithelppage&action=edit edithelppage]<br> -[[MediaWiki_talk:Edithelppage|Talk]] -</td><td> -Help:Editing -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editing&action=edit editing]<br> -[[MediaWiki_talk:Editing|Talk]] -</td><td> -Editing $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editingold&action=edit editingold]<br> -[[MediaWiki_talk:Editingold|Talk]] -</td><td> -&lt;strong&gt;WARNING: You are editing an out-of-date -revision of this page. -If you save it, any changes made since this revision will be lost.&lt;/strong&gt; - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editsection&action=edit editsection]<br> -[[MediaWiki_talk:Editsection|Talk]] -</td><td> -edit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editthispage&action=edit editthispage]<br> -[[MediaWiki_talk:Editthispage|Talk]] -</td><td> -Edit this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailflag&action=edit emailflag]<br> -[[MediaWiki_talk:Emailflag|Talk]] -</td><td> -Disable e-mail from other users -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailforlost&action=edit emailforlost]<br> -[[MediaWiki_talk:Emailforlost|Talk]] -</td><td> -Fields marked with a star (*) are optional. Storing an email address enables people to contact you through the website without you having to reveal your -email address to them, and it can be used to send you a new password if you forget it.&lt;br /&gt;&lt;br /&gt;Your real name, if you choose to provide it, will be used for giving you attribution for your work. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailfrom&action=edit emailfrom]<br> -[[MediaWiki_talk:Emailfrom|Talk]] -</td><td> -From -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailmessage&action=edit emailmessage]<br> -[[MediaWiki_talk:Emailmessage|Talk]] -</td><td> -Message -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpage&action=edit emailpage]<br> -[[MediaWiki_talk:Emailpage|Talk]] -</td><td> -E-mail user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpagetext&action=edit emailpagetext]<br> -[[MediaWiki_talk:Emailpagetext|Talk]] -</td><td> -If this user has entered a valid e-mail address in -his or her user preferences, the form below will send a single message. -The e-mail address you entered in your user preferences will appear -as the &quot;From&quot; address of the mail, so the recipient will be able -to reply. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsend&action=edit emailsend]<br> -[[MediaWiki_talk:Emailsend|Talk]] -</td><td> -Send -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsent&action=edit emailsent]<br> -[[MediaWiki_talk:Emailsent|Talk]] -</td><td> -E-mail sent -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsenttext&action=edit emailsenttext]<br> -[[MediaWiki_talk:Emailsenttext|Talk]] -</td><td> -Your e-mail message has been sent. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsubject&action=edit emailsubject]<br> -[[MediaWiki_talk:Emailsubject|Talk]] -</td><td> -Subject -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailto&action=edit emailto]<br> -[[MediaWiki_talk:Emailto|Talk]] -</td><td> -To -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailuser&action=edit emailuser]<br> -[[MediaWiki_talk:Emailuser|Talk]] -</td><td> -E-mail this user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Enterlockreason&action=edit enterlockreason]<br> -[[MediaWiki_talk:Enterlockreason|Talk]] -</td><td> -Enter a reason for the lock, including an estimate -of when the lock will be released -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Error&action=edit error]<br> -[[MediaWiki_talk:Error|Talk]] -</td><td> -Error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Errorpagetitle&action=edit errorpagetitle]<br> -[[MediaWiki_talk:Errorpagetitle|Talk]] -</td><td> -Error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exbeforeblank&action=edit exbeforeblank]<br> -[[MediaWiki_talk:Exbeforeblank|Talk]] -</td><td> -content before blanking was: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exblank&action=edit exblank]<br> -[[MediaWiki_talk:Exblank|Talk]] -</td><td> -page was empty -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Excontent&action=edit excontent]<br> -[[MediaWiki_talk:Excontent|Talk]] -</td><td> -content was: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Explainconflict&action=edit explainconflict]<br> -[[MediaWiki_talk:Explainconflict|Talk]] -</td><td> -Someone else has changed this page since you -started editing it. -The upper text area contains the page text as it currently exists. -Your changes are shown in the lower text area. -You will have to merge your changes into the existing text. -&lt;b&gt;Only&lt;/b&gt; the text in the upper text area will be saved when you -press &quot;Save page&quot;. -&lt;p&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Export&action=edit export]<br> -[[MediaWiki_talk:Export|Talk]] -</td><td> -Export pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exportcuronly&action=edit exportcuronly]<br> -[[MediaWiki_talk:Exportcuronly|Talk]] -</td><td> -Include only the current revision, not the full history -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exporttext&action=edit exporttext]<br> -[[MediaWiki_talk:Exporttext|Talk]] -</td><td> -You can export the text and editing history of a particular -page or set of pages wrapped in some XML; this can then be imported into another -wiki running MediaWiki software, transformed, or just kept for your private -amusement. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Extlink_sample&action=edit extlink_sample]<br> -[[MediaWiki_talk:Extlink_sample|Talk]] -</td><td> -http&#58;//www.example.com link title -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Extlink_tip&action=edit extlink_tip]<br> -[[MediaWiki_talk:Extlink_tip|Talk]] -</td><td> -External link (remember http&#58;// prefix) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Faq&action=edit faq]<br> -[[MediaWiki_talk:Faq|Talk]] -</td><td> -FAQ -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Faqpage&action=edit faqpage]<br> -[[MediaWiki_talk:Faqpage|Talk]] -</td><td> -Wiktionary:FAQ -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Feedlinks&action=edit feedlinks]<br> -[[MediaWiki_talk:Feedlinks|Talk]] -</td><td> -Feed: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filecopyerror&action=edit filecopyerror]<br> -[[MediaWiki_talk:Filecopyerror|Talk]] -</td><td> -Could not copy file &quot;$1&quot; to &quot;$2&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filedeleteerror&action=edit filedeleteerror]<br> -[[MediaWiki_talk:Filedeleteerror|Talk]] -</td><td> -Could not delete file &quot;$1&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filedesc&action=edit filedesc]<br> -[[MediaWiki_talk:Filedesc|Talk]] -</td><td> -Summary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filename&action=edit filename]<br> -[[MediaWiki_talk:Filename|Talk]] -</td><td> -Filename -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filenotfound&action=edit filenotfound]<br> -[[MediaWiki_talk:Filenotfound|Talk]] -</td><td> -Could not find file &quot;$1&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filerenameerror&action=edit filerenameerror]<br> -[[MediaWiki_talk:Filerenameerror|Talk]] -</td><td> -Could not rename file &quot;$1&quot; to &quot;$2&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filesource&action=edit filesource]<br> -[[MediaWiki_talk:Filesource|Talk]] -</td><td> -Source -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filestatus&action=edit filestatus]<br> -[[MediaWiki_talk:Filestatus|Talk]] -</td><td> -Copyright status -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Fileuploaded&action=edit fileuploaded]<br> -[[MediaWiki_talk:Fileuploaded|Talk]] -</td><td> -File &quot;$1&quot; uploaded successfully. -Please follow this link: $2 to the description page and fill -in information about the file, such as where it came from, when it was -created and by whom, and anything else you may know about it. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Formerror&action=edit formerror]<br> -[[MediaWiki_talk:Formerror|Talk]] -</td><td> -Error: could not submit form -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Fromwikipedia&action=edit fromwikipedia]<br> -[[MediaWiki_talk:Fromwikipedia|Talk]] -</td><td> -From Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Getimagelist&action=edit getimagelist]<br> -[[MediaWiki_talk:Getimagelist|Talk]] -</td><td> -fetching image list -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Go&action=edit go]<br> -[[MediaWiki_talk:Go|Talk]] -</td><td> -Go -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Googlesearch&action=edit googlesearch]<br> -[[MediaWiki_talk:Googlesearch|Talk]] -</td><td> - -&lt;!-- SiteSearch Google --&gt; -&lt;FORM method=GET action=&quot;http&#58;//www.google.com/search&quot;&gt; -&lt;TABLE bgcolor=&quot;#FFFFFF&quot;&gt;&lt;tr&gt;&lt;td&gt; -&lt;A HREF=&quot;http&#58;//www.google.com/&quot;&gt; -&lt;IMG SRC=&quot;http&#58;//www.google.com/logos/Logo_40wht.gif&quot; -border=&quot;0&quot; ALT=&quot;Google&quot;&gt;&lt;/A&gt; -&lt;/td&gt; -&lt;td&gt; -&lt;INPUT TYPE=text name=q size=31 maxlength=255 value=&quot;$1&quot;&gt; -&lt;INPUT type=submit name=btnG VALUE=&quot;Google Search&quot;&gt; -&lt;font size=-1&gt; -&lt;input type=hidden name=domains value=&quot;http&#58;//tl.wiktionary.org&quot;&gt;&lt;br /&gt;&lt;input type=radio name=sitesearch value=&quot;&quot;&gt; WWW &lt;input type=radio name=sitesearch value=&quot;http&#58;//tl.wiktionary.org&quot; checked&gt; http&#58;//tl.wiktionary.org &lt;br /&gt; -&lt;input type=&#39;hidden&#39; name=&#39;ie&#39; value=&#39;$2&#39;&gt; -&lt;input type=&#39;hidden&#39; name=&#39;oe&#39; value=&#39;$2&#39;&gt; -&lt;/font&gt; -&lt;/td&gt;&lt;/tr&gt;&lt;/TABLE&gt; -&lt;/FORM&gt; -&lt;!-- SiteSearch Google --&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Guesstimezone&action=edit guesstimezone]<br> -[[MediaWiki_talk:Guesstimezone|Talk]] -</td><td> -Fill in from browser -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Headline_sample&action=edit headline_sample]<br> -[[MediaWiki_talk:Headline_sample|Talk]] -</td><td> -Headline text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Headline_tip&action=edit headline_tip]<br> -[[MediaWiki_talk:Headline_tip|Talk]] -</td><td> -Level 2 headline -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Help&action=edit help]<br> -[[MediaWiki_talk:Help|Talk]] -</td><td> -Help -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Helppage&action=edit helppage]<br> -[[MediaWiki_talk:Helppage|Talk]] -</td><td> -Help:Contents -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hide&action=edit hide]<br> -[[MediaWiki_talk:Hide|Talk]] -</td><td> -hide -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hidetoc&action=edit hidetoc]<br> -[[MediaWiki_talk:Hidetoc|Talk]] -</td><td> -hide -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hist&action=edit hist]<br> -[[MediaWiki_talk:Hist|Talk]] -</td><td> -hist -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Histlegend&action=edit histlegend]<br> -[[MediaWiki_talk:Histlegend|Talk]] -</td><td> -Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.&lt;br/&gt; -Legend: (cur) = difference with current version, -(last) = difference with preceding version, M = minor edit. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:History&action=edit history]<br> -[[MediaWiki_talk:History|Talk]] -</td><td> -Page history -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:History_short&action=edit history_short]<br> -[[MediaWiki_talk:History_short|Talk]] -</td><td> -History -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Historywarning&action=edit historywarning]<br> -[[MediaWiki_talk:Historywarning|Talk]] -</td><td> -Warning: The page you are about to delete has a history: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hr_tip&action=edit hr_tip]<br> -[[MediaWiki_talk:Hr_tip|Talk]] -</td><td> -Horizontal line (use sparingly) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ignorewarning&action=edit ignorewarning]<br> -[[MediaWiki_talk:Ignorewarning|Talk]] -</td><td> -Ignore warning and save file anyway. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ilshowmatch&action=edit ilshowmatch]<br> -[[MediaWiki_talk:Ilshowmatch|Talk]] -</td><td> -Show all images with names matching -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ilsubmit&action=edit ilsubmit]<br> -[[MediaWiki_talk:Ilsubmit|Talk]] -</td><td> -Search -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Image_sample&action=edit image_sample]<br> -[[MediaWiki_talk:Image_sample|Talk]] -</td><td> -Example.jpg -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Image_tip&action=edit image_tip]<br> -[[MediaWiki_talk:Image_tip|Talk]] -</td><td> -Embedded image -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelinks&action=edit imagelinks]<br> -[[MediaWiki_talk:Imagelinks|Talk]] -</td><td> -Image links -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelist&action=edit imagelist]<br> -[[MediaWiki_talk:Imagelist|Talk]] -</td><td> -Image list -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelisttext&action=edit imagelisttext]<br> -[[MediaWiki_talk:Imagelisttext|Talk]] -</td><td> -Below is a list of $1 images sorted $2. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagepage&action=edit imagepage]<br> -[[MediaWiki_talk:Imagepage|Talk]] -</td><td> -View image page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagereverted&action=edit imagereverted]<br> -[[MediaWiki_talk:Imagereverted|Talk]] -</td><td> -Revert to earlier version was successful. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imgdelete&action=edit imgdelete]<br> -[[MediaWiki_talk:Imgdelete|Talk]] -</td><td> -del -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imgdesc&action=edit imgdesc]<br> -[[MediaWiki_talk:Imgdesc|Talk]] -</td><td> -desc -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imghistlegend&action=edit imghistlegend]<br> -[[MediaWiki_talk:Imghistlegend|Talk]] -</td><td> -Legend: (cur) = this is the current image, (del) = delete -this old version, (rev) = revert to this old version. -&lt;br /&gt;&lt;i&gt;Click on date to see image uploaded on that date&lt;/i&gt;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imghistory&action=edit imghistory]<br> -[[MediaWiki_talk:Imghistory|Talk]] -</td><td> -Image history -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imglegend&action=edit imglegend]<br> -[[MediaWiki_talk:Imglegend|Talk]] -</td><td> -Legend: (desc) = show/edit image description. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Import&action=edit import]<br> -[[MediaWiki_talk:Import|Talk]] -</td><td> -Import pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importfailed&action=edit importfailed]<br> -[[MediaWiki_talk:Importfailed|Talk]] -</td><td> -Import failed: $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importhistoryconflict&action=edit importhistoryconflict]<br> -[[MediaWiki_talk:Importhistoryconflict|Talk]] -</td><td> -Conflicting history revision exists (may have imported this page before) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importnotext&action=edit importnotext]<br> -[[MediaWiki_talk:Importnotext|Talk]] -</td><td> -Empty or no text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importsuccess&action=edit importsuccess]<br> -[[MediaWiki_talk:Importsuccess|Talk]] -</td><td> -Import succeeded! -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importtext&action=edit importtext]<br> -[[MediaWiki_talk:Importtext|Talk]] -</td><td> -Please export the file from the source wiki using the Special:Export utility, save it to your disk and upload it here. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Infobox&action=edit infobox]<br> -[[MediaWiki_talk:Infobox|Talk]] -</td><td> -Click a button to get an example text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Infobox_alert&action=edit infobox_alert]<br> -[[MediaWiki_talk:Infobox_alert|Talk]] -</td><td> -Please enter the text you want to be formatted.\n It will be shown in the infobox for copy and pasting.\nExample:\n$1\nwill become:\n$2 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Internalerror&action=edit internalerror]<br> -[[MediaWiki_talk:Internalerror|Talk]] -</td><td> -Internal error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Intl&action=edit intl]<br> -[[MediaWiki_talk:Intl|Talk]] -</td><td> -Interlanguage links -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ip_range_invalid&action=edit ip_range_invalid]<br> -[[MediaWiki_talk:Ip_range_invalid|Talk]] -</td><td> -Invalid IP range. - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipaddress&action=edit ipaddress]<br> -[[MediaWiki_talk:Ipaddress|Talk]] -</td><td> -IP Address/username -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipb_expiry_invalid&action=edit ipb_expiry_invalid]<br> -[[MediaWiki_talk:Ipb_expiry_invalid|Talk]] -</td><td> -Expiry time invalid. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbexpiry&action=edit ipbexpiry]<br> -[[MediaWiki_talk:Ipbexpiry|Talk]] -</td><td> -Expiry -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipblocklist&action=edit ipblocklist]<br> -[[MediaWiki_talk:Ipblocklist|Talk]] -</td><td> -List of blocked IP addresses and usernames -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbreason&action=edit ipbreason]<br> -[[MediaWiki_talk:Ipbreason|Talk]] -</td><td> -Reason -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbsubmit&action=edit ipbsubmit]<br> -[[MediaWiki_talk:Ipbsubmit|Talk]] -</td><td> -Block this user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipusubmit&action=edit ipusubmit]<br> -[[MediaWiki_talk:Ipusubmit|Talk]] -</td><td> -Unblock this address -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipusuccess&action=edit ipusuccess]<br> -[[MediaWiki_talk:Ipusuccess|Talk]] -</td><td> -&quot;$1&quot; unblocked -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Isbn&action=edit isbn]<br> -[[MediaWiki_talk:Isbn|Talk]] -</td><td> -ISBN -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Isredirect&action=edit isredirect]<br> -[[MediaWiki_talk:Isredirect|Talk]] -</td><td> -redirect page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Italic_sample&action=edit italic_sample]<br> -[[MediaWiki_talk:Italic_sample|Talk]] -</td><td> -Italic text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Italic_tip&action=edit italic_tip]<br> -[[MediaWiki_talk:Italic_tip|Talk]] -</td><td> -Italic text -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Iteminvalidname&action=edit iteminvalidname]<br> -[[MediaWiki_talk:Iteminvalidname|Talk]] -</td><td> -Problem with item &#39;$1&#39;, invalid name... -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Largefile&action=edit largefile]<br> -[[MediaWiki_talk:Largefile|Talk]] -</td><td> -It is recommended that images not exceed 100k in size. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Last&action=edit last]<br> -[[MediaWiki_talk:Last|Talk]] -</td><td> -last -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lastmodified&action=edit lastmodified]<br> -[[MediaWiki_talk:Lastmodified|Talk]] -</td><td> -This page was last modified $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lastmodifiedby&action=edit lastmodifiedby]<br> -[[MediaWiki_talk:Lastmodifiedby|Talk]] -</td><td> -This page was last modified $1 by $2. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lineno&action=edit lineno]<br> -[[MediaWiki_talk:Lineno|Talk]] -</td><td> -Line $1: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Link_sample&action=edit link_sample]<br> -[[MediaWiki_talk:Link_sample|Talk]] -</td><td> -Link title -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Link_tip&action=edit link_tip]<br> -[[MediaWiki_talk:Link_tip|Talk]] -</td><td> -Internal link -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linklistsub&action=edit linklistsub]<br> -[[MediaWiki_talk:Linklistsub|Talk]] -</td><td> -(List of links) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linkshere&action=edit linkshere]<br> -[[MediaWiki_talk:Linkshere|Talk]] -</td><td> -The following pages link to here: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linkstoimage&action=edit linkstoimage]<br> -[[MediaWiki_talk:Linkstoimage|Talk]] -</td><td> -The following pages link to this image: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linktrail&action=edit linktrail]<br> -[[MediaWiki_talk:Linktrail|Talk]] -</td><td> -/^(&#91;a-z]+)(.*)$/sD -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Listform&action=edit listform]<br> -[[MediaWiki_talk:Listform|Talk]] -</td><td> -list -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Listusers&action=edit listusers]<br> -[[MediaWiki_talk:Listusers|Talk]] -</td><td> -User list -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loadhist&action=edit loadhist]<br> -[[MediaWiki_talk:Loadhist|Talk]] -</td><td> -Loading page history -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loadingrev&action=edit loadingrev]<br> -[[MediaWiki_talk:Loadingrev|Talk]] -</td><td> -loading revision for diff -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Localtime&action=edit localtime]<br> -[[MediaWiki_talk:Localtime|Talk]] -</td><td> -Local time display -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockbtn&action=edit lockbtn]<br> -[[MediaWiki_talk:Lockbtn|Talk]] -</td><td> -Lock database -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockconfirm&action=edit lockconfirm]<br> -[[MediaWiki_talk:Lockconfirm|Talk]] -</td><td> -Yes, I really want to lock the database. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdb&action=edit lockdb]<br> -[[MediaWiki_talk:Lockdb|Talk]] -</td><td> -Lock database -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbsuccesssub&action=edit lockdbsuccesssub]<br> -[[MediaWiki_talk:Lockdbsuccesssub|Talk]] -</td><td> -Database lock succeeded -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbsuccesstext&action=edit lockdbsuccesstext]<br> -[[MediaWiki_talk:Lockdbsuccesstext|Talk]] -</td><td> -The database has been locked. -&lt;br /&gt;Remember to remove the lock after your maintenance is complete. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbtext&action=edit lockdbtext]<br> -[[MediaWiki_talk:Lockdbtext|Talk]] -</td><td> -Locking the database will suspend the ability of all -users to edit pages, change their preferences, edit their watchlists, and -other things requiring changes in the database. -Please confirm that this is what you intend to do, and that you will -unlock the database when your maintenance is done. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Locknoconfirm&action=edit locknoconfirm]<br> -[[MediaWiki_talk:Locknoconfirm|Talk]] -</td><td> -You did not check the confirmation box. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Login&action=edit login]<br> -[[MediaWiki_talk:Login|Talk]] -</td><td> -Log in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginend&action=edit loginend]<br> -[[MediaWiki_talk:Loginend|Talk]] -</td><td> -&amp;nbsp; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginerror&action=edit loginerror]<br> -[[MediaWiki_talk:Loginerror|Talk]] -</td><td> -Login error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginpagetitle&action=edit loginpagetitle]<br> -[[MediaWiki_talk:Loginpagetitle|Talk]] -</td><td> -User login -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginproblem&action=edit loginproblem]<br> -[[MediaWiki_talk:Loginproblem|Talk]] -</td><td> -&lt;b&gt;There has been a problem with your login.&lt;/b&gt;&lt;br /&gt;Try again! -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginprompt&action=edit loginprompt]<br> -[[MediaWiki_talk:Loginprompt|Talk]] -</td><td> -You must have cookies enabled to log in to Wiktionary. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginreqtext&action=edit loginreqtext]<br> -[[MediaWiki_talk:Loginreqtext|Talk]] -</td><td> -You must &#91;&#91;special:Userlogin&#124;login]] to view other pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginreqtitle&action=edit loginreqtitle]<br> -[[MediaWiki_talk:Loginreqtitle|Talk]] -</td><td> -Login Required -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginsuccess&action=edit loginsuccess]<br> -[[MediaWiki_talk:Loginsuccess|Talk]] -</td><td> -You are now logged in to Wiktionary as &quot;$1&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginsuccesstitle&action=edit loginsuccesstitle]<br> -[[MediaWiki_talk:Loginsuccesstitle|Talk]] -</td><td> -Login successful -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logout&action=edit logout]<br> -[[MediaWiki_talk:Logout|Talk]] -</td><td> -Log out -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logouttext&action=edit logouttext]<br> -[[MediaWiki_talk:Logouttext|Talk]] -</td><td> -You are now logged out. -You can continue to use Wiktionary anonymously, or you can log in -again as the same or as a different user. Note that some pages may -continue to be displayed as if you were still logged in, until you clear -your browser cache - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logouttitle&action=edit logouttitle]<br> -[[MediaWiki_talk:Logouttitle|Talk]] -</td><td> -User logout -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lonelypages&action=edit lonelypages]<br> -[[MediaWiki_talk:Lonelypages|Talk]] -</td><td> -Orphaned pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Longpages&action=edit longpages]<br> -[[MediaWiki_talk:Longpages|Talk]] -</td><td> -Long pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Longpagewarning&action=edit longpagewarning]<br> -[[MediaWiki_talk:Longpagewarning|Talk]] -</td><td> -WARNING: This page is $1 kilobytes long; some -browsers may have problems editing pages approaching or longer than 32kb. -Please consider breaking the page into smaller sections. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailerror&action=edit mailerror]<br> -[[MediaWiki_talk:Mailerror|Talk]] -</td><td> -Error sending mail: $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailmypassword&action=edit mailmypassword]<br> -[[MediaWiki_talk:Mailmypassword|Talk]] -</td><td> -Mail me a new password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailnologin&action=edit mailnologin]<br> -[[MediaWiki_talk:Mailnologin|Talk]] -</td><td> -No send address -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailnologintext&action=edit mailnologintext]<br> -[[MediaWiki_talk:Mailnologintext|Talk]] -</td><td> -You must be &lt;a href=&quot;{{localurl:Special:Userlogin&quot;&gt;logged in&lt;/a&gt; -and have a valid e-mail address in your &lt;a href=&quot;/wiki/Special:Preferences&quot;&gt;preferences&lt;/a&gt; -to send e-mail to other users. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpage&action=edit mainpage]<br> -[[MediaWiki_talk:Mainpage|Talk]] -</td><td> -Main Page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpagedocfooter&action=edit mainpagedocfooter]<br> -[[MediaWiki_talk:Mainpagedocfooter|Talk]] -</td><td> -Please see &#91;http&#58;//meta.wikipedia.org/wiki/MediaWiki_i18n documentation on customizing the interface] -and the &#91;http&#58;//meta.wikipedia.org/wiki/MediaWiki_User%27s_Guide User&#39;s Guide] for usage and configuration help. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpagetext&action=edit mainpagetext]<br> -[[MediaWiki_talk:Mainpagetext|Talk]] -</td><td> -Wiki software successfully installed. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintenance&action=edit maintenance]<br> -[[MediaWiki_talk:Maintenance|Talk]] -</td><td> -Maintenance page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintenancebacklink&action=edit maintenancebacklink]<br> -[[MediaWiki_talk:Maintenancebacklink|Talk]] -</td><td> -Back to Maintenance Page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintnancepagetext&action=edit maintnancepagetext]<br> -[[MediaWiki_talk:Maintnancepagetext|Talk]] -</td><td> -This page includes several handy tools for everyday maintenance. Some of these functions tend to stress the database, so please do not hit reload after every item you fixed ;-) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysop&action=edit makesysop]<br> -[[MediaWiki_talk:Makesysop|Talk]] -</td><td> -Make a user into a sysop -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopfail&action=edit makesysopfail]<br> -[[MediaWiki_talk:Makesysopfail|Talk]] -</td><td> -&lt;b&gt;User &quot;$1&quot; could not be made into a sysop. (Did you enter the name correctly?)&lt;/b&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopname&action=edit makesysopname]<br> -[[MediaWiki_talk:Makesysopname|Talk]] -</td><td> -Name of the user: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopok&action=edit makesysopok]<br> -[[MediaWiki_talk:Makesysopok|Talk]] -</td><td> -&lt;b&gt;User &quot;$1&quot; is now a sysop&lt;/b&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopsubmit&action=edit makesysopsubmit]<br> -[[MediaWiki_talk:Makesysopsubmit|Talk]] -</td><td> -Make this user into a sysop -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysoptext&action=edit makesysoptext]<br> -[[MediaWiki_talk:Makesysoptext|Talk]] -</td><td> -This form is used by bureaucrats to turn ordinary users into administrators. -Type the name of the user in the box and press the button to make the user an administrator -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysoptitle&action=edit makesysoptitle]<br> -[[MediaWiki_talk:Makesysoptitle|Talk]] -</td><td> -Make a user into a sysop -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Matchtotals&action=edit matchtotals]<br> -[[MediaWiki_talk:Matchtotals|Talk]] -</td><td> -The query &quot;$1&quot; matched $2 page titles -and the text of $3 pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math&action=edit math]<br> -[[MediaWiki_talk:Math|Talk]] -</td><td> -Rendering math -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_bad_output&action=edit math_bad_output]<br> -[[MediaWiki_talk:Math_bad_output|Talk]] -</td><td> -Can&#39;t write to or create math output directory -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_bad_tmpdir&action=edit math_bad_tmpdir]<br> -[[MediaWiki_talk:Math_bad_tmpdir|Talk]] -</td><td> -Can&#39;t write to or create math temp directory -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_failure&action=edit math_failure]<br> -[[MediaWiki_talk:Math_failure|Talk]] -</td><td> -Failed to parse -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_image_error&action=edit math_image_error]<br> -[[MediaWiki_talk:Math_image_error|Talk]] -</td><td> -PNG conversion failed; check for correct installation of latex, dvips, gs, and convert -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_lexing_error&action=edit math_lexing_error]<br> -[[MediaWiki_talk:Math_lexing_error|Talk]] -</td><td> -lexing error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_notexvc&action=edit math_notexvc]<br> -[[MediaWiki_talk:Math_notexvc|Talk]] -</td><td> -Missing texvc executable; please see math/README to configure. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_sample&action=edit math_sample]<br> -[[MediaWiki_talk:Math_sample|Talk]] -</td><td> -Insert formula here -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_syntax_error&action=edit math_syntax_error]<br> -[[MediaWiki_talk:Math_syntax_error|Talk]] -</td><td> -syntax error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_tip&action=edit math_tip]<br> -[[MediaWiki_talk:Math_tip|Talk]] -</td><td> -Mathematical formula (LaTeX) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_unknown_error&action=edit math_unknown_error]<br> -[[MediaWiki_talk:Math_unknown_error|Talk]] -</td><td> -unknown error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_unknown_function&action=edit math_unknown_function]<br> -[[MediaWiki_talk:Math_unknown_function|Talk]] -</td><td> -unknown function -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Media_sample&action=edit media_sample]<br> -[[MediaWiki_talk:Media_sample|Talk]] -</td><td> -Example.mp3 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Media_tip&action=edit media_tip]<br> -[[MediaWiki_talk:Media_tip|Talk]] -</td><td> -Media file link -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minlength&action=edit minlength]<br> -[[MediaWiki_talk:Minlength|Talk]] -</td><td> -Image names must be at least three letters. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minoredit&action=edit minoredit]<br> -[[MediaWiki_talk:Minoredit|Talk]] -</td><td> -This is a minor edit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minoreditletter&action=edit minoreditletter]<br> -[[MediaWiki_talk:Minoreditletter|Talk]] -</td><td> -M -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelings&action=edit mispeelings]<br> -[[MediaWiki_talk:Mispeelings|Talk]] -</td><td> -Pages with misspellings -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelingspage&action=edit mispeelingspage]<br> -[[MediaWiki_talk:Mispeelingspage|Talk]] -</td><td> -List of common misspellings -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelingstext&action=edit mispeelingstext]<br> -[[MediaWiki_talk:Mispeelingstext|Talk]] -</td><td> -The following pages contain a common misspelling, which are listed on $1. The correct spelling might be given (like this). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missingarticle&action=edit missingarticle]<br> -[[MediaWiki_talk:Missingarticle|Talk]] -</td><td> -The database did not find the text of a page -that it should have found, named &quot;$1&quot;. - -&lt;p&gt;This is usually caused by following an outdated diff or history link to a -page that has been deleted. - -&lt;p&gt;If this is not the case, you may have found a bug in the software. -Please report this to an administrator, making note of the URL. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missingimage&action=edit missingimage]<br> -[[MediaWiki_talk:Missingimage|Talk]] -</td><td> -&lt;b&gt;Missing image&lt;/b&gt;&lt;br /&gt;&lt;i&gt;$1&lt;/i&gt; - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinks&action=edit missinglanguagelinks]<br> -[[MediaWiki_talk:Missinglanguagelinks|Talk]] -</td><td> -Missing Language Links -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinksbutton&action=edit missinglanguagelinksbutton]<br> -[[MediaWiki_talk:Missinglanguagelinksbutton|Talk]] -</td><td> -Find missing language links for -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinkstext&action=edit missinglanguagelinkstext]<br> -[[MediaWiki_talk:Missinglanguagelinkstext|Talk]] -</td><td> -These pages do &lt;i&gt;not&lt;/i&gt; link to their counterpart in $1. Redirects and subpages are &lt;i&gt;not&lt;/i&gt; shown. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Moredotdotdot&action=edit moredotdotdot]<br> -[[MediaWiki_talk:Moredotdotdot|Talk]] -</td><td> -More... -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Move&action=edit move]<br> -[[MediaWiki_talk:Move|Talk]] -</td><td> -Move -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movearticle&action=edit movearticle]<br> -[[MediaWiki_talk:Movearticle|Talk]] -</td><td> -Move page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movedto&action=edit movedto]<br> -[[MediaWiki_talk:Movedto|Talk]] -</td><td> -moved to -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movenologin&action=edit movenologin]<br> -[[MediaWiki_talk:Movenologin|Talk]] -</td><td> -Not logged in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movenologintext&action=edit movenologintext]<br> -[[MediaWiki_talk:Movenologintext|Talk]] -</td><td> -You must be a registered user and &lt;a href=&quot;/wiki/Special:Userlogin&quot;&gt;logged in&lt;/a&gt; -to move a page. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepage&action=edit movepage]<br> -[[MediaWiki_talk:Movepage|Talk]] -</td><td> -Move page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagebtn&action=edit movepagebtn]<br> -[[MediaWiki_talk:Movepagebtn|Talk]] -</td><td> -Move page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagetalktext&action=edit movepagetalktext]<br> -[[MediaWiki_talk:Movepagetalktext|Talk]] -</td><td> -The associated talk page, if any, will be automatically moved along with it &#39;&#39;&#39;unless:&#39;&#39;&#39; -*You are moving the page across namespaces, -*A non-empty talk page already exists under the new name, or -*You uncheck the box below. - -In those cases, you will have to move or merge the page manually if desired. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagetext&action=edit movepagetext]<br> -[[MediaWiki_talk:Movepagetext|Talk]] -</td><td> -Using the form below will rename a page, moving all -of its history to the new name. -The old title will become a redirect page to the new title. -Links to the old page title will not be changed; be sure to -&#91;&#91;Special:Maintenance&#124;check]] for double or broken redirects. -You are responsible for making sure that links continue to -point where they are supposed to go. - -Note that the page will &#39;&#39;&#39;not&#39;&#39;&#39; be moved if there is already -a page at the new title, unless it is empty or a redirect and has no -past edit history. This means that you can rename a page back to where -it was just renamed from if you make a mistake, and you cannot overwrite -an existing page. - -&lt;b&gt;WARNING!&lt;/b&gt; -This can be a drastic and unexpected change for a popular page; -please be sure you understand the consequences of this before -proceeding. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movetalk&action=edit movetalk]<br> -[[MediaWiki_talk:Movetalk|Talk]] -</td><td> -Move &quot;talk&quot; page as well, if applicable. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movethispage&action=edit movethispage]<br> -[[MediaWiki_talk:Movethispage|Talk]] -</td><td> -Move this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mycontris&action=edit mycontris]<br> -[[MediaWiki_talk:Mycontris|Talk]] -</td><td> -My contributions -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mypage&action=edit mypage]<br> -[[MediaWiki_talk:Mypage|Talk]] -</td><td> -My page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mytalk&action=edit mytalk]<br> -[[MediaWiki_talk:Mytalk|Talk]] -</td><td> -My talk -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Navigation&action=edit navigation]<br> -[[MediaWiki_talk:Navigation|Talk]] -</td><td> -Navigation -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nbytes&action=edit nbytes]<br> -[[MediaWiki_talk:Nbytes|Talk]] -</td><td> -$1 bytes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nchanges&action=edit nchanges]<br> -[[MediaWiki_talk:Nchanges|Talk]] -</td><td> -$1 changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newarticle&action=edit newarticle]<br> -[[MediaWiki_talk:Newarticle|Talk]] -</td><td> -(New) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newarticletext&action=edit newarticletext]<br> -[[MediaWiki_talk:Newarticletext|Talk]] -</td><td> -You&#39;ve followed a link to a page that doesn&#39;t exist yet. -To create the page, start typing in the box below -(see the &#91;&#91;Wiktionary:Help&#124;help page]] for more info). -If you are here by mistake, just click your browser&#39;s &#39;&#39;&#39;back&#39;&#39;&#39; button. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newmessages&action=edit newmessages]<br> -[[MediaWiki_talk:Newmessages|Talk]] -</td><td> -You have $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newmessageslink&action=edit newmessageslink]<br> -[[MediaWiki_talk:Newmessageslink|Talk]] -</td><td> -new messages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpage&action=edit newpage]<br> -[[MediaWiki_talk:Newpage|Talk]] -</td><td> -New page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpageletter&action=edit newpageletter]<br> -[[MediaWiki_talk:Newpageletter|Talk]] -</td><td> -N -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpages&action=edit newpages]<br> -[[MediaWiki_talk:Newpages|Talk]] -</td><td> -New pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpassword&action=edit newpassword]<br> -[[MediaWiki_talk:Newpassword|Talk]] -</td><td> -New password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newtitle&action=edit newtitle]<br> -[[MediaWiki_talk:Newtitle|Talk]] -</td><td> -To new title -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newusersonly&action=edit newusersonly]<br> -[[MediaWiki_talk:Newusersonly|Talk]] -</td><td> - (new users only) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Next&action=edit next]<br> -[[MediaWiki_talk:Next|Talk]] -</td><td> -next -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nextn&action=edit nextn]<br> -[[MediaWiki_talk:Nextn|Talk]] -</td><td> -next $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nlinks&action=edit nlinks]<br> -[[MediaWiki_talk:Nlinks|Talk]] -</td><td> -$1 links -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noaffirmation&action=edit noaffirmation]<br> -[[MediaWiki_talk:Noaffirmation|Talk]] -</td><td> -You must affirm that your upload does not violate -any copyrights. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noarticletext&action=edit noarticletext]<br> -[[MediaWiki_talk:Noarticletext|Talk]] -</td><td> -(There is currently no text in this page) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noblockreason&action=edit noblockreason]<br> -[[MediaWiki_talk:Noblockreason|Talk]] -</td><td> -You must supply a reason for the block. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noconnect&action=edit noconnect]<br> -[[MediaWiki_talk:Noconnect|Talk]] -</td><td> -Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocontribs&action=edit nocontribs]<br> -[[MediaWiki_talk:Nocontribs|Talk]] -</td><td> -No changes were found matching these criteria. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocookieslogin&action=edit nocookieslogin]<br> -[[MediaWiki_talk:Nocookieslogin|Talk]] -</td><td> -Wiktionary uses cookies to log in users. You have cookies disabled. Please enable them and try again. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocookiesnew&action=edit nocookiesnew]<br> -[[MediaWiki_talk:Nocookiesnew|Talk]] -</td><td> -The user account was created, but you are not logged in. Wiktionary uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocreativecommons&action=edit nocreativecommons]<br> -[[MediaWiki_talk:Nocreativecommons|Talk]] -</td><td> -Creative Commons RDF metadata disabled for this server. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nodb&action=edit nodb]<br> -[[MediaWiki_talk:Nodb|Talk]] -</td><td> -Could not select database $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nodublincore&action=edit nodublincore]<br> -[[MediaWiki_talk:Nodublincore|Talk]] -</td><td> -Dublin Core RDF metadata disabled for this server. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemail&action=edit noemail]<br> -[[MediaWiki_talk:Noemail|Talk]] -</td><td> -There is no e-mail address recorded for user &quot;$1&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemailtext&action=edit noemailtext]<br> -[[MediaWiki_talk:Noemailtext|Talk]] -</td><td> -This user has not specified a valid e-mail address, -or has chosen not to receive e-mail from other users. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemailtitle&action=edit noemailtitle]<br> -[[MediaWiki_talk:Noemailtitle|Talk]] -</td><td> -No e-mail address -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nogomatch&action=edit nogomatch]<br> -[[MediaWiki_talk:Nogomatch|Talk]] -</td><td> -No page with this exact title exists, trying full text search. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nohistory&action=edit nohistory]<br> -[[MediaWiki_talk:Nohistory|Talk]] -</td><td> -There is no edit history for this page. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nolinkshere&action=edit nolinkshere]<br> -[[MediaWiki_talk:Nolinkshere|Talk]] -</td><td> -No pages link to here. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nolinkstoimage&action=edit nolinkstoimage]<br> -[[MediaWiki_talk:Nolinkstoimage|Talk]] -</td><td> -There are no pages that link to this image. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noname&action=edit noname]<br> -[[MediaWiki_talk:Noname|Talk]] -</td><td> -You have not specified a valid user name. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nonefound&action=edit nonefound]<br> -[[MediaWiki_talk:Nonefound|Talk]] -</td><td> -&lt;strong&gt;Note&lt;/strong&gt;: unsuccessful searches are -often caused by searching for common words like &quot;have&quot; and &quot;from&quot;, -which are not indexed, or by specifying more than one search term (only pages -containing all of the search terms will appear in the result). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nospecialpagetext&action=edit nospecialpagetext]<br> -[[MediaWiki_talk:Nospecialpagetext|Talk]] -</td><td> -You have requested a special page that is not -recognized by the wiki. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchaction&action=edit nosuchaction]<br> -[[MediaWiki_talk:Nosuchaction|Talk]] -</td><td> -No such action -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchactiontext&action=edit nosuchactiontext]<br> -[[MediaWiki_talk:Nosuchactiontext|Talk]] -</td><td> -The action specified by the URL is not -recognized by the wiki -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchspecialpage&action=edit nosuchspecialpage]<br> -[[MediaWiki_talk:Nosuchspecialpage|Talk]] -</td><td> -No such special page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchuser&action=edit nosuchuser]<br> -[[MediaWiki_talk:Nosuchuser|Talk]] -</td><td> -There is no user by the name &quot;$1&quot;. -Check your spelling, or use the form below to create a new user account. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notacceptable&action=edit notacceptable]<br> -[[MediaWiki_talk:Notacceptable|Talk]] -</td><td> -The wiki server can&#39;t provide data in a format your client can read. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notanarticle&action=edit notanarticle]<br> -[[MediaWiki_talk:Notanarticle|Talk]] -</td><td> -Not a content page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notargettext&action=edit notargettext]<br> -[[MediaWiki_talk:Notargettext|Talk]] -</td><td> -You have not specified a target page or user -to perform this function on. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notargettitle&action=edit notargettitle]<br> -[[MediaWiki_talk:Notargettitle|Talk]] -</td><td> -No target -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Note&action=edit note]<br> -[[MediaWiki_talk:Note|Talk]] -</td><td> -&lt;strong&gt;Note:&lt;/strong&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notextmatches&action=edit notextmatches]<br> -[[MediaWiki_talk:Notextmatches|Talk]] -</td><td> -No page text matches -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notitlematches&action=edit notitlematches]<br> -[[MediaWiki_talk:Notitlematches|Talk]] -</td><td> -No page title matches -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notloggedin&action=edit notloggedin]<br> -[[MediaWiki_talk:Notloggedin|Talk]] -</td><td> -Not logged in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowatchlist&action=edit nowatchlist]<br> -[[MediaWiki_talk:Nowatchlist|Talk]] -</td><td> -You have no items on your watchlist. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowiki_sample&action=edit nowiki_sample]<br> -[[MediaWiki_talk:Nowiki_sample|Talk]] -</td><td> -Insert non-formatted text here -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowiki_tip&action=edit nowiki_tip]<br> -[[MediaWiki_talk:Nowiki_tip|Talk]] -</td><td> -Ignore wiki formatting -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-category&action=edit nstab-category]<br> -[[MediaWiki_talk:Nstab-category|Talk]] -</td><td> -Category -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-help&action=edit nstab-help]<br> -[[MediaWiki_talk:Nstab-help|Talk]] -</td><td> -Help -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-image&action=edit nstab-image]<br> -[[MediaWiki_talk:Nstab-image|Talk]] -</td><td> -Image -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-main&action=edit nstab-main]<br> -[[MediaWiki_talk:Nstab-main|Talk]] -</td><td> -Article -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-media&action=edit nstab-media]<br> -[[MediaWiki_talk:Nstab-media|Talk]] -</td><td> -Media -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-mediawiki&action=edit nstab-mediawiki]<br> -[[MediaWiki_talk:Nstab-mediawiki|Talk]] -</td><td> -Message -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-special&action=edit nstab-special]<br> -[[MediaWiki_talk:Nstab-special|Talk]] -</td><td> -Special -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-template&action=edit nstab-template]<br> -[[MediaWiki_talk:Nstab-template|Talk]] -</td><td> -Template -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-user&action=edit nstab-user]<br> -[[MediaWiki_talk:Nstab-user|Talk]] -</td><td> -User page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-wp&action=edit nstab-wp]<br> -[[MediaWiki_talk:Nstab-wp|Talk]] -</td><td> -About -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nviews&action=edit nviews]<br> -[[MediaWiki_talk:Nviews|Talk]] -</td><td> -$1 views -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ok&action=edit ok]<br> -[[MediaWiki_talk:Ok|Talk]] -</td><td> -OK -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Oldpassword&action=edit oldpassword]<br> -[[MediaWiki_talk:Oldpassword|Talk]] -</td><td> -Old password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Orig&action=edit orig]<br> -[[MediaWiki_talk:Orig|Talk]] -</td><td> -orig -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Orphans&action=edit orphans]<br> -[[MediaWiki_talk:Orphans|Talk]] -</td><td> -Orphaned pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Othercontribs&action=edit othercontribs]<br> -[[MediaWiki_talk:Othercontribs|Talk]] -</td><td> -Based on work by $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Otherlanguages&action=edit otherlanguages]<br> -[[MediaWiki_talk:Otherlanguages|Talk]] -</td><td> -Other languages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagemovedsub&action=edit pagemovedsub]<br> -[[MediaWiki_talk:Pagemovedsub|Talk]] -</td><td> -Move succeeded -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagemovedtext&action=edit pagemovedtext]<br> -[[MediaWiki_talk:Pagemovedtext|Talk]] -</td><td> -Page &quot;&#91;&#91;$1]]&quot; moved to &quot;&#91;&#91;$2]]&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagetitle&action=edit pagetitle]<br> -[[MediaWiki_talk:Pagetitle|Talk]] -</td><td> -$1 - Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordremindertext&action=edit passwordremindertext]<br> -[[MediaWiki_talk:Passwordremindertext|Talk]] -</td><td> -Someone (probably you, from IP address $1) -requested that we send you a new Wiktionary login password. -The password for user &quot;$2&quot; is now &quot;$3&quot;. -You should log in and change your password now. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordremindertitle&action=edit passwordremindertitle]<br> -[[MediaWiki_talk:Passwordremindertitle|Talk]] -</td><td> -Password reminder from Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordsent&action=edit passwordsent]<br> -[[MediaWiki_talk:Passwordsent|Talk]] -</td><td> -A new password has been sent to the e-mail address -registered for &quot;$1&quot;. -Please log in again after you receive it. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfcached&action=edit perfcached]<br> -[[MediaWiki_talk:Perfcached|Talk]] -</td><td> -The following data is cached and may not be completely up to date: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfdisabled&action=edit perfdisabled]<br> -[[MediaWiki_talk:Perfdisabled|Talk]] -</td><td> -Sorry! This feature has been temporarily disabled -because it slows the database down to the point that no one can use -the wiki. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfdisabledsub&action=edit perfdisabledsub]<br> -[[MediaWiki_talk:Perfdisabledsub|Talk]] -</td><td> -Here&#39;s a saved copy from $1: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Personaltools&action=edit personaltools]<br> -[[MediaWiki_talk:Personaltools|Talk]] -</td><td> -Personal tools -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Popularpages&action=edit popularpages]<br> -[[MediaWiki_talk:Popularpages|Talk]] -</td><td> -Popular pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Portal&action=edit portal]<br> -[[MediaWiki_talk:Portal|Talk]] -</td><td> -Community portal -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Portal-url&action=edit portal-url]<br> -[[MediaWiki_talk:Portal-url|Talk]] -</td><td> -Wiktionary:Community Portal -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Postcomment&action=edit postcomment]<br> -[[MediaWiki_talk:Postcomment|Talk]] -</td><td> -Post a comment -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Poweredby&action=edit poweredby]<br> -[[MediaWiki_talk:Poweredby|Talk]] -</td><td> -Wiktionary is powered by &#91;http&#58;//www.mediawiki.org/ MediaWiki], an open source wiki engine. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Powersearch&action=edit powersearch]<br> -[[MediaWiki_talk:Powersearch|Talk]] -</td><td> -Search -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Powersearchtext&action=edit powersearchtext]<br> -[[MediaWiki_talk:Powersearchtext|Talk]] -</td><td> - -Search in namespaces :&lt;br /&gt; -$1&lt;br /&gt; -$2 List redirects &amp;nbsp; Search for $3 $9 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Preferences&action=edit preferences]<br> -[[MediaWiki_talk:Preferences|Talk]] -</td><td> -Preferences -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-help-userdata&action=edit prefs-help-userdata]<br> -[[MediaWiki_talk:Prefs-help-userdata|Talk]] -</td><td> -* &lt;strong&gt;Real name&lt;/strong&gt; (optional): if you choose to provide it this will be used for giving you attribution for your work.&lt;br/&gt; -* &lt;strong&gt;Email&lt;/strong&gt; (optional): Enables people to contact you through the website without you having to reveal your -email address to them, and it can be used to send you a new password if you forget it. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-misc&action=edit prefs-misc]<br> -[[MediaWiki_talk:Prefs-misc|Talk]] -</td><td> -Misc settings -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-personal&action=edit prefs-personal]<br> -[[MediaWiki_talk:Prefs-personal|Talk]] -</td><td> -User data -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-rc&action=edit prefs-rc]<br> -[[MediaWiki_talk:Prefs-rc|Talk]] -</td><td> -Recent changes and stub display -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefslogintext&action=edit prefslogintext]<br> -[[MediaWiki_talk:Prefslogintext|Talk]] -</td><td> -You are logged in as &quot;$1&quot;. -Your internal ID number is $2. - -See &#91;&#91;Wiktionary:User preferences help]] for help deciphering the options. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsnologin&action=edit prefsnologin]<br> -[[MediaWiki_talk:Prefsnologin|Talk]] -</td><td> -Not logged in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsnologintext&action=edit prefsnologintext]<br> -[[MediaWiki_talk:Prefsnologintext|Talk]] -</td><td> -You must be &lt;a href=&quot;/wiki/Special:Userlogin&quot;&gt;logged in&lt;/a&gt; -to set user preferences. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsreset&action=edit prefsreset]<br> -[[MediaWiki_talk:Prefsreset|Talk]] -</td><td> -Preferences have been reset from storage. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Preview&action=edit preview]<br> -[[MediaWiki_talk:Preview|Talk]] -</td><td> -Preview -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Previewconflict&action=edit previewconflict]<br> -[[MediaWiki_talk:Previewconflict|Talk]] -</td><td> -This preview reflects the text in the upper -text editing area as it will appear if you choose to save. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Previewnote&action=edit previewnote]<br> -[[MediaWiki_talk:Previewnote|Talk]] -</td><td> -Remember that this is only a preview, and has not yet been saved! -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prevn&action=edit prevn]<br> -[[MediaWiki_talk:Prevn|Talk]] -</td><td> -previous $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Printableversion&action=edit printableversion]<br> -[[MediaWiki_talk:Printableversion|Talk]] -</td><td> -Printable version -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Printsubtitle&action=edit printsubtitle]<br> -[[MediaWiki_talk:Printsubtitle|Talk]] -</td><td> -(From http&#58;//tl.wiktionary.org) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protect&action=edit protect]<br> -[[MediaWiki_talk:Protect|Talk]] -</td><td> -Protect -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectcomment&action=edit protectcomment]<br> -[[MediaWiki_talk:Protectcomment|Talk]] -</td><td> -Reason for protecting -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedarticle&action=edit protectedarticle]<br> -[[MediaWiki_talk:Protectedarticle|Talk]] -</td><td> -protected &#91;&#91;$1]] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedpage&action=edit protectedpage]<br> -[[MediaWiki_talk:Protectedpage|Talk]] -</td><td> -Protected page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedpagewarning&action=edit protectedpagewarning]<br> -[[MediaWiki_talk:Protectedpagewarning|Talk]] -</td><td> -WARNING: This page has been locked so that only -users with sysop privileges can edit it. Be sure you are following the -&lt;a href=&#39;/w/wiki.phtml/Wiktionary:Protected_page_guidelines&#39;&gt;protected page -guidelines&lt;/a&gt;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedtext&action=edit protectedtext]<br> -[[MediaWiki_talk:Protectedtext|Talk]] -</td><td> -This page has been locked to prevent editing; there are -a number of reasons why this may be so, please see -&#91;&#91;Wiktionary:Protected page]]. - -You can view and copy the source of this page: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectlogpage&action=edit protectlogpage]<br> -[[MediaWiki_talk:Protectlogpage|Talk]] -</td><td> -Protection_log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectlogtext&action=edit protectlogtext]<br> -[[MediaWiki_talk:Protectlogtext|Talk]] -</td><td> -Below is a list of page locks/unlocks. -See &#91;&#91;Wiktionary:Protected page]] for more information. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectpage&action=edit protectpage]<br> -[[MediaWiki_talk:Protectpage|Talk]] -</td><td> -Protect page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectreason&action=edit protectreason]<br> -[[MediaWiki_talk:Protectreason|Talk]] -</td><td> -(give a reason) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectsub&action=edit protectsub]<br> -[[MediaWiki_talk:Protectsub|Talk]] -</td><td> -(Protecting &quot;$1&quot;) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectthispage&action=edit protectthispage]<br> -[[MediaWiki_talk:Protectthispage|Talk]] -</td><td> -Protect this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblocker&action=edit proxyblocker]<br> -[[MediaWiki_talk:Proxyblocker|Talk]] -</td><td> -Proxy blocker -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblockreason&action=edit proxyblockreason]<br> -[[MediaWiki_talk:Proxyblockreason|Talk]] -</td><td> -Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblocksuccess&action=edit proxyblocksuccess]<br> -[[MediaWiki_talk:Proxyblocksuccess|Talk]] -</td><td> -Done. - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbbrowse&action=edit qbbrowse]<br> -[[MediaWiki_talk:Qbbrowse|Talk]] -</td><td> -Browse -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbedit&action=edit qbedit]<br> -[[MediaWiki_talk:Qbedit|Talk]] -</td><td> -Edit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbfind&action=edit qbfind]<br> -[[MediaWiki_talk:Qbfind|Talk]] -</td><td> -Find -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbmyoptions&action=edit qbmyoptions]<br> -[[MediaWiki_talk:Qbmyoptions|Talk]] -</td><td> -My pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbpageinfo&action=edit qbpageinfo]<br> -[[MediaWiki_talk:Qbpageinfo|Talk]] -</td><td> -Context -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbpageoptions&action=edit qbpageoptions]<br> -[[MediaWiki_talk:Qbpageoptions|Talk]] -</td><td> -This page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbsettings&action=edit qbsettings]<br> -[[MediaWiki_talk:Qbsettings|Talk]] -</td><td> -Quickbar settings -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbspecialpages&action=edit qbspecialpages]<br> -[[MediaWiki_talk:Qbspecialpages|Talk]] -</td><td> -Special pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Querybtn&action=edit querybtn]<br> -[[MediaWiki_talk:Querybtn|Talk]] -</td><td> -Submit query -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Querysuccessful&action=edit querysuccessful]<br> -[[MediaWiki_talk:Querysuccessful|Talk]] -</td><td> -Query successful -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Randompage&action=edit randompage]<br> -[[MediaWiki_talk:Randompage|Talk]] -</td><td> -Random page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Range_block_disabled&action=edit range_block_disabled]<br> -[[MediaWiki_talk:Range_block_disabled|Talk]] -</td><td> -The sysop ability to create range blocks is disabled. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rchide&action=edit rchide]<br> -[[MediaWiki_talk:Rchide|Talk]] -</td><td> -in $4 form; $1 minor edits; $2 secondary namespaces; $3 multiple edits. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclinks&action=edit rclinks]<br> -[[MediaWiki_talk:Rclinks|Talk]] -</td><td> -Show last $1 changes in last $2 days&lt;br /&gt;$3 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclistfrom&action=edit rclistfrom]<br> -[[MediaWiki_talk:Rclistfrom|Talk]] -</td><td> -Show new changes starting from $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcliu&action=edit rcliu]<br> -[[MediaWiki_talk:Rcliu|Talk]] -</td><td> -; $1 edits from logged in users -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcloaderr&action=edit rcloaderr]<br> -[[MediaWiki_talk:Rcloaderr|Talk]] -</td><td> -Loading recent changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclsub&action=edit rclsub]<br> -[[MediaWiki_talk:Rclsub|Talk]] -</td><td> -(to pages linked from &quot;$1&quot;) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcnote&action=edit rcnote]<br> -[[MediaWiki_talk:Rcnote|Talk]] -</td><td> -Below are the last &lt;strong&gt;$1&lt;/strong&gt; changes in last &lt;strong&gt;$2&lt;/strong&gt; days. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcnotefrom&action=edit rcnotefrom]<br> -[[MediaWiki_talk:Rcnotefrom|Talk]] -</td><td> -Below are the changes since &lt;b&gt;$2&lt;/b&gt; (up to &lt;b&gt;$1&lt;/b&gt; shown). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonly&action=edit readonly]<br> -[[MediaWiki_talk:Readonly|Talk]] -</td><td> -Database locked -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonlytext&action=edit readonlytext]<br> -[[MediaWiki_talk:Readonlytext|Talk]] -</td><td> -The database is currently locked to new -entries and other modifications, probably for routine database maintenance, -after which it will be back to normal. -The administrator who locked it offered this explanation: -&lt;p&gt;$1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonlywarning&action=edit readonlywarning]<br> -[[MediaWiki_talk:Readonlywarning|Talk]] -</td><td> -WARNING: The database has been locked for maintenance, -so you will not be able to save your edits right now. You may wish to cut-n-paste -the text into a text file and save it for later. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchanges&action=edit recentchanges]<br> -[[MediaWiki_talk:Recentchanges|Talk]] -</td><td> -Recent changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangescount&action=edit recentchangescount]<br> -[[MediaWiki_talk:Recentchangescount|Talk]] -</td><td> -Number of titles in recent changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangeslinked&action=edit recentchangeslinked]<br> -[[MediaWiki_talk:Recentchangeslinked|Talk]] -</td><td> -Related changes -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangestext&action=edit recentchangestext]<br> -[[MediaWiki_talk:Recentchangestext|Talk]] -</td><td> -Track the most recent changes to the wiki on this page. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Redirectedfrom&action=edit redirectedfrom]<br> -[[MediaWiki_talk:Redirectedfrom|Talk]] -</td><td> -(Redirected from $1) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Remembermypassword&action=edit remembermypassword]<br> -[[MediaWiki_talk:Remembermypassword|Talk]] -</td><td> -Remember my password across sessions. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removechecked&action=edit removechecked]<br> -[[MediaWiki_talk:Removechecked|Talk]] -</td><td> -Remove checked items from watchlist -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removedwatch&action=edit removedwatch]<br> -[[MediaWiki_talk:Removedwatch|Talk]] -</td><td> -Removed from watchlist -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removedwatchtext&action=edit removedwatchtext]<br> -[[MediaWiki_talk:Removedwatchtext|Talk]] -</td><td> -The page &quot;$1&quot; has been removed from your watchlist. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removingchecked&action=edit removingchecked]<br> -[[MediaWiki_talk:Removingchecked|Talk]] -</td><td> -Removing requested items from watchlist... -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Resetprefs&action=edit resetprefs]<br> -[[MediaWiki_talk:Resetprefs|Talk]] -</td><td> -Reset preferences -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Restorelink&action=edit restorelink]<br> -[[MediaWiki_talk:Restorelink|Talk]] -</td><td> -$1 deleted edits -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Resultsperpage&action=edit resultsperpage]<br> -[[MediaWiki_talk:Resultsperpage|Talk]] -</td><td> -Hits to show per page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Retrievedfrom&action=edit retrievedfrom]<br> -[[MediaWiki_talk:Retrievedfrom|Talk]] -</td><td> -Retrieved from &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Returnto&action=edit returnto]<br> -[[MediaWiki_talk:Returnto|Talk]] -</td><td> -Return to $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Retypenew&action=edit retypenew]<br> -[[MediaWiki_talk:Retypenew|Talk]] -</td><td> -Retype new password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reupload&action=edit reupload]<br> -[[MediaWiki_talk:Reupload|Talk]] -</td><td> -Re-upload -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reuploaddesc&action=edit reuploaddesc]<br> -[[MediaWiki_talk:Reuploaddesc|Talk]] -</td><td> -Return to the upload form. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reverted&action=edit reverted]<br> -[[MediaWiki_talk:Reverted|Talk]] -</td><td> -Reverted to earlier revision -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revertimg&action=edit revertimg]<br> -[[MediaWiki_talk:Revertimg|Talk]] -</td><td> -rev -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revertpage&action=edit revertpage]<br> -[[MediaWiki_talk:Revertpage|Talk]] -</td><td> -Reverted edit of $2, changed back to last version by $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revhistory&action=edit revhistory]<br> -[[MediaWiki_talk:Revhistory|Talk]] -</td><td> -Revision history -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revisionasof&action=edit revisionasof]<br> -[[MediaWiki_talk:Revisionasof|Talk]] -</td><td> -Revision as of $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revnotfound&action=edit revnotfound]<br> -[[MediaWiki_talk:Revnotfound|Talk]] -</td><td> -Revision not found -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revnotfoundtext&action=edit revnotfoundtext]<br> -[[MediaWiki_talk:Revnotfoundtext|Talk]] -</td><td> -The old revision of the page you asked for could not be found. -Please check the URL you used to access this page. - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rfcurl&action=edit rfcurl]<br> -[[MediaWiki_talk:Rfcurl|Talk]] -</td><td> -http&#58;//www.faqs.org/rfcs/rfc$1.html -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rights&action=edit rights]<br> -[[MediaWiki_talk:Rights|Talk]] -</td><td> -Rights: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollback&action=edit rollback]<br> -[[MediaWiki_talk:Rollback|Talk]] -</td><td> -Roll back edits -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollback_short&action=edit rollback_short]<br> -[[MediaWiki_talk:Rollback_short|Talk]] -</td><td> -Rollback -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollbackfailed&action=edit rollbackfailed]<br> -[[MediaWiki_talk:Rollbackfailed|Talk]] -</td><td> -Rollback failed -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollbacklink&action=edit rollbacklink]<br> -[[MediaWiki_talk:Rollbacklink|Talk]] -</td><td> -rollback -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rows&action=edit rows]<br> -[[MediaWiki_talk:Rows|Talk]] -</td><td> -Rows -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savearticle&action=edit savearticle]<br> -[[MediaWiki_talk:Savearticle|Talk]] -</td><td> -Save page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savedprefs&action=edit savedprefs]<br> -[[MediaWiki_talk:Savedprefs|Talk]] -</td><td> -Your preferences have been saved. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savefile&action=edit savefile]<br> -[[MediaWiki_talk:Savefile|Talk]] -</td><td> -Save file -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Saveprefs&action=edit saveprefs]<br> -[[MediaWiki_talk:Saveprefs|Talk]] -</td><td> -Save preferences -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Search&action=edit search]<br> -[[MediaWiki_talk:Search|Talk]] -</td><td> -Search -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchdisabled&action=edit searchdisabled]<br> -[[MediaWiki_talk:Searchdisabled|Talk]] -</td><td> -&lt;p&gt;Sorry! Full text search has been disabled temporarily, for performance reasons. In the meantime, you can use the Google search below, which may be out of date.&lt;/p&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchhelppage&action=edit searchhelppage]<br> -[[MediaWiki_talk:Searchhelppage|Talk]] -</td><td> -Wiktionary:Searching -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchingwikipedia&action=edit searchingwikipedia]<br> -[[MediaWiki_talk:Searchingwikipedia|Talk]] -</td><td> -Searching Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchquery&action=edit searchquery]<br> -[[MediaWiki_talk:Searchquery|Talk]] -</td><td> -For query &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresults&action=edit searchresults]<br> -[[MediaWiki_talk:Searchresults|Talk]] -</td><td> -Search results -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresultshead&action=edit searchresultshead]<br> -[[MediaWiki_talk:Searchresultshead|Talk]] -</td><td> -Search result settings -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresulttext&action=edit searchresulttext]<br> -[[MediaWiki_talk:Searchresulttext|Talk]] -</td><td> -For more information about searching Wiktionary, see $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sectionedit&action=edit sectionedit]<br> -[[MediaWiki_talk:Sectionedit|Talk]] -</td><td> - (section) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectnewerversionfordiff&action=edit selectnewerversionfordiff]<br> -[[MediaWiki_talk:Selectnewerversionfordiff|Talk]] -</td><td> -Select a newer version for comparison -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectolderversionfordiff&action=edit selectolderversionfordiff]<br> -[[MediaWiki_talk:Selectolderversionfordiff|Talk]] -</td><td> -Select an older version for comparison -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectonly&action=edit selectonly]<br> -[[MediaWiki_talk:Selectonly|Talk]] -</td><td> -Only read-only queries are allowed. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selflinks&action=edit selflinks]<br> -[[MediaWiki_talk:Selflinks|Talk]] -</td><td> -Pages with Self Links -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selflinkstext&action=edit selflinkstext]<br> -[[MediaWiki_talk:Selflinkstext|Talk]] -</td><td> -The following pages contain a link to themselves, which they should not. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Seriousxhtmlerrors&action=edit seriousxhtmlerrors]<br> -[[MediaWiki_talk:Seriousxhtmlerrors|Talk]] -</td><td> -There were serious xhtml markup errors detected by tidy. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Servertime&action=edit servertime]<br> -[[MediaWiki_talk:Servertime|Talk]] -</td><td> -Server time is now -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Set_rights_fail&action=edit set_rights_fail]<br> -[[MediaWiki_talk:Set_rights_fail|Talk]] -</td><td> -&lt;b&gt;User rights for &quot;$1&quot; could not be set. (Did you enter the name correctly?)&lt;/b&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Set_user_rights&action=edit set_user_rights]<br> -[[MediaWiki_talk:Set_user_rights|Talk]] -</td><td> -Set user rights -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Setbureaucratflag&action=edit setbureaucratflag]<br> -[[MediaWiki_talk:Setbureaucratflag|Talk]] -</td><td> -Set bureaucrat flag -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Shortpages&action=edit shortpages]<br> -[[MediaWiki_talk:Shortpages|Talk]] -</td><td> -Short pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Show&action=edit show]<br> -[[MediaWiki_talk:Show|Talk]] -</td><td> -show -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showhideminor&action=edit showhideminor]<br> -[[MediaWiki_talk:Showhideminor|Talk]] -</td><td> -$1 minor edits &#124; $2 bots &#124; $3 logged in users -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showingresults&action=edit showingresults]<br> -[[MediaWiki_talk:Showingresults|Talk]] -</td><td> -Showing below &lt;b&gt;$1&lt;/b&gt; results starting with #&lt;b&gt;$2&lt;/b&gt;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showingresultsnum&action=edit showingresultsnum]<br> -[[MediaWiki_talk:Showingresultsnum|Talk]] -</td><td> -Showing below &lt;b&gt;$3&lt;/b&gt; results starting with #&lt;b&gt;$2&lt;/b&gt;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showlast&action=edit showlast]<br> -[[MediaWiki_talk:Showlast|Talk]] -</td><td> -Show last $1 images sorted $2. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showpreview&action=edit showpreview]<br> -[[MediaWiki_talk:Showpreview|Talk]] -</td><td> -Show preview -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showtoc&action=edit showtoc]<br> -[[MediaWiki_talk:Showtoc|Talk]] -</td><td> -show -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sig_tip&action=edit sig_tip]<br> -[[MediaWiki_talk:Sig_tip|Talk]] -</td><td> -Your signature with timestamp -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitestats&action=edit sitestats]<br> -[[MediaWiki_talk:Sitestats|Talk]] -</td><td> -Site statistics -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitestatstext&action=edit sitestatstext]<br> -[[MediaWiki_talk:Sitestatstext|Talk]] -</td><td> -There are &#39;&#39;&#39;$1&#39;&#39;&#39; total pages in the database. -This includes &quot;talk&quot; pages, pages about Wiktionary, minimal &quot;stub&quot; -pages, redirects, and others that probably don&#39;t qualify as content pages. -Excluding those, there are &#39;&#39;&#39;$2&#39;&#39;&#39; pages that are probably legitimate -content pages. - -There have been a total of &#39;&#39;&#39;$3&#39;&#39;&#39; page views, and &#39;&#39;&#39;$4&#39;&#39;&#39; page edits -since the wiki was setup. -That comes to &#39;&#39;&#39;$5&#39;&#39;&#39; average edits per page, and &#39;&#39;&#39;$6&#39;&#39;&#39; views per edit. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitesubtitle&action=edit sitesubtitle]<br> -[[MediaWiki_talk:Sitesubtitle|Talk]] -</td><td> -The Free Encyclopedia -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitesupport&action=edit sitesupport]<br> -[[MediaWiki_talk:Sitesupport|Talk]] -</td><td> -Donations -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitetitle&action=edit sitetitle]<br> -[[MediaWiki_talk:Sitetitle|Talk]] -</td><td> -Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Siteuser&action=edit siteuser]<br> -[[MediaWiki_talk:Siteuser|Talk]] -</td><td> -Wiktionary user $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Siteusers&action=edit siteusers]<br> -[[MediaWiki_talk:Siteusers|Talk]] -</td><td> -Wiktionary user(s) $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Skin&action=edit skin]<br> -[[MediaWiki_talk:Skin|Talk]] -</td><td> -Skin -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spamprotectiontext&action=edit spamprotectiontext]<br> -[[MediaWiki_talk:Spamprotectiontext|Talk]] -</td><td> -The page you wanted to save was blocked by the spam filter. This is probably caused by a link to an external site. - -You might want to check the following regular expression for patterns that are currently blocked: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spamprotectiontitle&action=edit spamprotectiontitle]<br> -[[MediaWiki_talk:Spamprotectiontitle|Talk]] -</td><td> -Spam protection filter -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Specialpage&action=edit specialpage]<br> -[[MediaWiki_talk:Specialpage|Talk]] -</td><td> -Special Page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Specialpages&action=edit specialpages]<br> -[[MediaWiki_talk:Specialpages|Talk]] -</td><td> -Special pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spheading&action=edit spheading]<br> -[[MediaWiki_talk:Spheading|Talk]] -</td><td> -Special pages for all users -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sqlislogged&action=edit sqlislogged]<br> -[[MediaWiki_talk:Sqlislogged|Talk]] -</td><td> -Please note that all queries are logged. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sqlquery&action=edit sqlquery]<br> -[[MediaWiki_talk:Sqlquery|Talk]] -</td><td> -Enter query -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Statistics&action=edit statistics]<br> -[[MediaWiki_talk:Statistics|Talk]] -</td><td> -Statistics -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Storedversion&action=edit storedversion]<br> -[[MediaWiki_talk:Storedversion|Talk]] -</td><td> -Stored version -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Stubthreshold&action=edit stubthreshold]<br> -[[MediaWiki_talk:Stubthreshold|Talk]] -</td><td> -Threshold for stub display -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subcategories&action=edit subcategories]<br> -[[MediaWiki_talk:Subcategories|Talk]] -</td><td> -Subcategories -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subject&action=edit subject]<br> -[[MediaWiki_talk:Subject|Talk]] -</td><td> -Subject/headline -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subjectpage&action=edit subjectpage]<br> -[[MediaWiki_talk:Subjectpage|Talk]] -</td><td> -View subject -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Successfulupload&action=edit successfulupload]<br> -[[MediaWiki_talk:Successfulupload|Talk]] -</td><td> -Successful upload -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Summary&action=edit summary]<br> -[[MediaWiki_talk:Summary|Talk]] -</td><td> -Summary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysopspheading&action=edit sysopspheading]<br> -[[MediaWiki_talk:Sysopspheading|Talk]] -</td><td> -For sysop use only -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysoptext&action=edit sysoptext]<br> -[[MediaWiki_talk:Sysoptext|Talk]] -</td><td> -The action you have requested can only be -performed by users with &quot;sysop&quot; status. -See $1. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysoptitle&action=edit sysoptitle]<br> -[[MediaWiki_talk:Sysoptitle|Talk]] -</td><td> -Sysop access required -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tableform&action=edit tableform]<br> -[[MediaWiki_talk:Tableform|Talk]] -</td><td> -table -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talk&action=edit talk]<br> -[[MediaWiki_talk:Talk|Talk]] -</td><td> -Discussion -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkexists&action=edit talkexists]<br> -[[MediaWiki_talk:Talkexists|Talk]] -</td><td> -The page itself was moved successfully, but the -talk page could not be moved because one already exists at the new -title. Please merge them manually. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpage&action=edit talkpage]<br> -[[MediaWiki_talk:Talkpage|Talk]] -</td><td> -Discuss this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagemoved&action=edit talkpagemoved]<br> -[[MediaWiki_talk:Talkpagemoved|Talk]] -</td><td> -The corresponding talk page was also moved. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagenotmoved&action=edit talkpagenotmoved]<br> -[[MediaWiki_talk:Talkpagenotmoved|Talk]] -</td><td> -The corresponding talk page was &lt;strong&gt;not&lt;/strong&gt; moved. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagetext&action=edit talkpagetext]<br> -[[MediaWiki_talk:Talkpagetext|Talk]] -</td><td> -&lt;!-- MediaWiki:talkpagetext --&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Textboxsize&action=edit textboxsize]<br> -[[MediaWiki_talk:Textboxsize|Talk]] -</td><td> -Textbox dimensions -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Textmatches&action=edit textmatches]<br> -[[MediaWiki_talk:Textmatches|Talk]] -</td><td> -Page text matches -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Thisisdeleted&action=edit thisisdeleted]<br> -[[MediaWiki_talk:Thisisdeleted|Talk]] -</td><td> -View or restore $1? -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Thumbnail-more&action=edit thumbnail-more]<br> -[[MediaWiki_talk:Thumbnail-more|Talk]] -</td><td> -Enlarge -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezonelegend&action=edit timezonelegend]<br> -[[MediaWiki_talk:Timezonelegend|Talk]] -</td><td> -Time zone -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezoneoffset&action=edit timezoneoffset]<br> -[[MediaWiki_talk:Timezoneoffset|Talk]] -</td><td> -Offset -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezonetext&action=edit timezonetext]<br> -[[MediaWiki_talk:Timezonetext|Talk]] -</td><td> -Enter number of hours your local time differs -from server time (UTC). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Titlematches&action=edit titlematches]<br> -[[MediaWiki_talk:Titlematches|Talk]] -</td><td> -Article title matches -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Toc&action=edit toc]<br> -[[MediaWiki_talk:Toc|Talk]] -</td><td> -Table of contents -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Toolbox&action=edit toolbox]<br> -[[MediaWiki_talk:Toolbox|Talk]] -</td><td> -Toolbox -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-addsection&action=edit tooltip-addsection]<br> -[[MediaWiki_talk:Tooltip-addsection|Talk]] -</td><td> -Add a comment to this page. &#91;alt-+] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-anontalk&action=edit tooltip-anontalk]<br> -[[MediaWiki_talk:Tooltip-anontalk|Talk]] -</td><td> -Discussion about edits from this ip address &#91;alt-n] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-anonuserpage&action=edit tooltip-anonuserpage]<br> -[[MediaWiki_talk:Tooltip-anonuserpage|Talk]] -</td><td> -The user page for the ip you&#39;re editing as &#91;alt-.] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-article&action=edit tooltip-article]<br> -[[MediaWiki_talk:Tooltip-article|Talk]] -</td><td> -View the content page &#91;alt-a] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-atom&action=edit tooltip-atom]<br> -[[MediaWiki_talk:Tooltip-atom|Talk]] -</td><td> -Atom feed for this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-compareselectedversions&action=edit tooltip-compareselectedversions]<br> -[[MediaWiki_talk:Tooltip-compareselectedversions|Talk]] -</td><td> -See the differences between the two selected versions of this page. &#91;alt-v] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-contributions&action=edit tooltip-contributions]<br> -[[MediaWiki_talk:Tooltip-contributions|Talk]] -</td><td> -View the list of contributions of this user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-currentevents&action=edit tooltip-currentevents]<br> -[[MediaWiki_talk:Tooltip-currentevents|Talk]] -</td><td> -Find background information on current events -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-delete&action=edit tooltip-delete]<br> -[[MediaWiki_talk:Tooltip-delete|Talk]] -</td><td> -Delete this page &#91;alt-d] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-edit&action=edit tooltip-edit]<br> -[[MediaWiki_talk:Tooltip-edit|Talk]] -</td><td> -You can edit this page. Please use the preview button before saving. &#91;alt-e] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-emailuser&action=edit tooltip-emailuser]<br> -[[MediaWiki_talk:Tooltip-emailuser|Talk]] -</td><td> -Send a mail to this user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-help&action=edit tooltip-help]<br> -[[MediaWiki_talk:Tooltip-help|Talk]] -</td><td> -The place to find out. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-history&action=edit tooltip-history]<br> -[[MediaWiki_talk:Tooltip-history|Talk]] -</td><td> -Past versions of this page, &#91;alt-h] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-login&action=edit tooltip-login]<br> -[[MediaWiki_talk:Tooltip-login|Talk]] -</td><td> -You are encouraged to log in, it is not mandatory however. &#91;alt-o] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-logout&action=edit tooltip-logout]<br> -[[MediaWiki_talk:Tooltip-logout|Talk]] -</td><td> -Log out &#91;alt-o] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mainpage&action=edit tooltip-mainpage]<br> -[[MediaWiki_talk:Tooltip-mainpage|Talk]] -</td><td> -Visit the Main Page &#91;alt-z] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-minoredit&action=edit tooltip-minoredit]<br> -[[MediaWiki_talk:Tooltip-minoredit|Talk]] -</td><td> -Mark this as a minor edit &#91;alt-i] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-move&action=edit tooltip-move]<br> -[[MediaWiki_talk:Tooltip-move|Talk]] -</td><td> -Move this page &#91;alt-m] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mycontris&action=edit tooltip-mycontris]<br> -[[MediaWiki_talk:Tooltip-mycontris|Talk]] -</td><td> -List of my contributions &#91;alt-y] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mytalk&action=edit tooltip-mytalk]<br> -[[MediaWiki_talk:Tooltip-mytalk|Talk]] -</td><td> -My talk page &#91;alt-n] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-nomove&action=edit tooltip-nomove]<br> -[[MediaWiki_talk:Tooltip-nomove|Talk]] -</td><td> -You don&#39;t have the permissions to move this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-portal&action=edit tooltip-portal]<br> -[[MediaWiki_talk:Tooltip-portal|Talk]] -</td><td> -About the project, what you can do, where to find things -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-preferences&action=edit tooltip-preferences]<br> -[[MediaWiki_talk:Tooltip-preferences|Talk]] -</td><td> -My preferences -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-preview&action=edit tooltip-preview]<br> -[[MediaWiki_talk:Tooltip-preview|Talk]] -</td><td> -Preview your changes, please use this before saving! &#91;alt-p] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-protect&action=edit tooltip-protect]<br> -[[MediaWiki_talk:Tooltip-protect|Talk]] -</td><td> -Protect this page &#91;alt-=] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-randompage&action=edit tooltip-randompage]<br> -[[MediaWiki_talk:Tooltip-randompage|Talk]] -</td><td> -Load a random page &#91;alt-x] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-recentchanges&action=edit tooltip-recentchanges]<br> -[[MediaWiki_talk:Tooltip-recentchanges|Talk]] -</td><td> -The list of recent changes in the wiki. &#91;alt-r] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-recentchangeslinked&action=edit tooltip-recentchangeslinked]<br> -[[MediaWiki_talk:Tooltip-recentchangeslinked|Talk]] -</td><td> -Recent changes in pages linking to this page &#91;alt-c] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-rss&action=edit tooltip-rss]<br> -[[MediaWiki_talk:Tooltip-rss|Talk]] -</td><td> -RSS feed for this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-save&action=edit tooltip-save]<br> -[[MediaWiki_talk:Tooltip-save|Talk]] -</td><td> -Save your changes &#91;alt-s] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-search&action=edit tooltip-search]<br> -[[MediaWiki_talk:Tooltip-search|Talk]] -</td><td> -Search this wiki &#91;alt-f] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-sitesupport&action=edit tooltip-sitesupport]<br> -[[MediaWiki_talk:Tooltip-sitesupport|Talk]] -</td><td> -Support Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-specialpage&action=edit tooltip-specialpage]<br> -[[MediaWiki_talk:Tooltip-specialpage|Talk]] -</td><td> -This is a special page, you can&#39;t edit the page itself. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-specialpages&action=edit tooltip-specialpages]<br> -[[MediaWiki_talk:Tooltip-specialpages|Talk]] -</td><td> -List of all special pages &#91;alt-q] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-talk&action=edit tooltip-talk]<br> -[[MediaWiki_talk:Tooltip-talk|Talk]] -</td><td> -Discussion about the content page &#91;alt-t] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-undelete&action=edit tooltip-undelete]<br> -[[MediaWiki_talk:Tooltip-undelete|Talk]] -</td><td> -Restore the $1 edits done to this page before it was deleted &#91;alt-d] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-unwatch&action=edit tooltip-unwatch]<br> -[[MediaWiki_talk:Tooltip-unwatch|Talk]] -</td><td> -Remove this page from your watchlist &#91;alt-w] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-upload&action=edit tooltip-upload]<br> -[[MediaWiki_talk:Tooltip-upload|Talk]] -</td><td> -Upload images or media files &#91;alt-u] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-userpage&action=edit tooltip-userpage]<br> -[[MediaWiki_talk:Tooltip-userpage|Talk]] -</td><td> -My user page &#91;alt-.] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-viewsource&action=edit tooltip-viewsource]<br> -[[MediaWiki_talk:Tooltip-viewsource|Talk]] -</td><td> -This page is protected. You can view its source. &#91;alt-e] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-watch&action=edit tooltip-watch]<br> -[[MediaWiki_talk:Tooltip-watch|Talk]] -</td><td> -Add this page to your watchlist &#91;alt-w] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-watchlist&action=edit tooltip-watchlist]<br> -[[MediaWiki_talk:Tooltip-watchlist|Talk]] -</td><td> -The list of pages you&#39;re monitoring for changes. &#91;alt-l] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-whatlinkshere&action=edit tooltip-whatlinkshere]<br> -[[MediaWiki_talk:Tooltip-whatlinkshere|Talk]] -</td><td> -List of all wiki pages that link here &#91;alt-b] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uclinks&action=edit uclinks]<br> -[[MediaWiki_talk:Uclinks|Talk]] -</td><td> -View the last $1 changes; view the last $2 days. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ucnote&action=edit ucnote]<br> -[[MediaWiki_talk:Ucnote|Talk]] -</td><td> -Below are this user&#39;s last &lt;b&gt;$1&lt;/b&gt; changes in the last &lt;b&gt;$2&lt;/b&gt; days. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uctop&action=edit uctop]<br> -[[MediaWiki_talk:Uctop|Talk]] -</td><td> - (top) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblockip&action=edit unblockip]<br> -[[MediaWiki_talk:Unblockip|Talk]] -</td><td> -Unblock user -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblockiptext&action=edit unblockiptext]<br> -[[MediaWiki_talk:Unblockiptext|Talk]] -</td><td> -Use the form below to restore write access -to a previously blocked IP address or username. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblocklink&action=edit unblocklink]<br> -[[MediaWiki_talk:Unblocklink|Talk]] -</td><td> -unblock -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblocklogentry&action=edit unblocklogentry]<br> -[[MediaWiki_talk:Unblocklogentry|Talk]] -</td><td> -unblocked &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undelete&action=edit undelete]<br> -[[MediaWiki_talk:Undelete|Talk]] -</td><td> -Restore deleted page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undelete_short&action=edit undelete_short]<br> -[[MediaWiki_talk:Undelete_short|Talk]] -</td><td> -Undelete $1 edits -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletearticle&action=edit undeletearticle]<br> -[[MediaWiki_talk:Undeletearticle|Talk]] -</td><td> -Restore deleted page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletebtn&action=edit undeletebtn]<br> -[[MediaWiki_talk:Undeletebtn|Talk]] -</td><td> -Restore! -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletedarticle&action=edit undeletedarticle]<br> -[[MediaWiki_talk:Undeletedarticle|Talk]] -</td><td> -restored &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletedtext&action=edit undeletedtext]<br> -[[MediaWiki_talk:Undeletedtext|Talk]] -</td><td> -&#91;&#91;$1]] has been successfully restored. -See &#91;&#91;Wiktionary:Deletion_log]] for a record of recent deletions and restorations. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletehistory&action=edit undeletehistory]<br> -[[MediaWiki_talk:Undeletehistory|Talk]] -</td><td> -If you restore the page, all revisions will be restored to the history. -If a new page with the same name has been created since the deletion, the restored -revisions will appear in the prior history, and the current revision of the live page -will not be automatically replaced. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletepage&action=edit undeletepage]<br> -[[MediaWiki_talk:Undeletepage|Talk]] -</td><td> -View and restore deleted pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletepagetext&action=edit undeletepagetext]<br> -[[MediaWiki_talk:Undeletepagetext|Talk]] -</td><td> -The following pages have been deleted but are still in the archive and -can be restored. The archive may be periodically cleaned out. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeleterevision&action=edit undeleterevision]<br> -[[MediaWiki_talk:Undeleterevision|Talk]] -</td><td> -Deleted revision as of $1 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeleterevisions&action=edit undeleterevisions]<br> -[[MediaWiki_talk:Undeleterevisions|Talk]] -</td><td> -$1 revisions archived -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unexpected&action=edit unexpected]<br> -[[MediaWiki_talk:Unexpected|Talk]] -</td><td> -Unexpected value: &quot;$1&quot;=&quot;$2&quot;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockbtn&action=edit unlockbtn]<br> -[[MediaWiki_talk:Unlockbtn|Talk]] -</td><td> -Unlock database -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockconfirm&action=edit unlockconfirm]<br> -[[MediaWiki_talk:Unlockconfirm|Talk]] -</td><td> -Yes, I really want to unlock the database. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdb&action=edit unlockdb]<br> -[[MediaWiki_talk:Unlockdb|Talk]] -</td><td> -Unlock database -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbsuccesssub&action=edit unlockdbsuccesssub]<br> -[[MediaWiki_talk:Unlockdbsuccesssub|Talk]] -</td><td> -Database lock removed -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbsuccesstext&action=edit unlockdbsuccesstext]<br> -[[MediaWiki_talk:Unlockdbsuccesstext|Talk]] -</td><td> -The database has been unlocked. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbtext&action=edit unlockdbtext]<br> -[[MediaWiki_talk:Unlockdbtext|Talk]] -</td><td> -Unlocking the database will restore the ability of all -users to edit pages, change their preferences, edit their watchlists, and -other things requiring changes in the database. -Please confirm that this is what you intend to do. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotect&action=edit unprotect]<br> -[[MediaWiki_talk:Unprotect|Talk]] -</td><td> -Unprotect -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectcomment&action=edit unprotectcomment]<br> -[[MediaWiki_talk:Unprotectcomment|Talk]] -</td><td> -Reason for unprotecting -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectedarticle&action=edit unprotectedarticle]<br> -[[MediaWiki_talk:Unprotectedarticle|Talk]] -</td><td> -unprotected &#91;&#91;$1]] -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectsub&action=edit unprotectsub]<br> -[[MediaWiki_talk:Unprotectsub|Talk]] -</td><td> -(Unprotecting &quot;$1&quot;) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectthispage&action=edit unprotectthispage]<br> -[[MediaWiki_talk:Unprotectthispage|Talk]] -</td><td> -Unprotect this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unusedimages&action=edit unusedimages]<br> -[[MediaWiki_talk:Unusedimages|Talk]] -</td><td> -Unused images -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unusedimagestext&action=edit unusedimagestext]<br> -[[MediaWiki_talk:Unusedimagestext|Talk]] -</td><td> -&lt;p&gt;Please note that other web sites may link to an image with -a direct URL, and so may still be listed here despite being -in active use. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unwatch&action=edit unwatch]<br> -[[MediaWiki_talk:Unwatch|Talk]] -</td><td> -Unwatch -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unwatchthispage&action=edit unwatchthispage]<br> -[[MediaWiki_talk:Unwatchthispage|Talk]] -</td><td> -Stop watching -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Updated&action=edit updated]<br> -[[MediaWiki_talk:Updated|Talk]] -</td><td> -(Updated) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Upload&action=edit upload]<br> -[[MediaWiki_talk:Upload|Talk]] -</td><td> -Upload file -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadbtn&action=edit uploadbtn]<br> -[[MediaWiki_talk:Uploadbtn|Talk]] -</td><td> -Upload file -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploaddisabled&action=edit uploaddisabled]<br> -[[MediaWiki_talk:Uploaddisabled|Talk]] -</td><td> -Sorry, uploading is disabled. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadedfiles&action=edit uploadedfiles]<br> -[[MediaWiki_talk:Uploadedfiles|Talk]] -</td><td> -Uploaded files -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadedimage&action=edit uploadedimage]<br> -[[MediaWiki_talk:Uploadedimage|Talk]] -</td><td> -uploaded &quot;$1&quot; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploaderror&action=edit uploaderror]<br> -[[MediaWiki_talk:Uploaderror|Talk]] -</td><td> -Upload error -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadfile&action=edit uploadfile]<br> -[[MediaWiki_talk:Uploadfile|Talk]] -</td><td> -Upload images, sounds, documents etc. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlink&action=edit uploadlink]<br> -[[MediaWiki_talk:Uploadlink|Talk]] -</td><td> -Upload images -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlog&action=edit uploadlog]<br> -[[MediaWiki_talk:Uploadlog|Talk]] -</td><td> -upload log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlogpage&action=edit uploadlogpage]<br> -[[MediaWiki_talk:Uploadlogpage|Talk]] -</td><td> -Upload_log -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlogpagetext&action=edit uploadlogpagetext]<br> -[[MediaWiki_talk:Uploadlogpagetext|Talk]] -</td><td> -Below is a list of the most recent file uploads. -All times shown are server time (UTC). -&lt;ul&gt; -&lt;/ul&gt; - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadnologin&action=edit uploadnologin]<br> -[[MediaWiki_talk:Uploadnologin|Talk]] -</td><td> -Not logged in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadnologintext&action=edit uploadnologintext]<br> -[[MediaWiki_talk:Uploadnologintext|Talk]] -</td><td> -You must be &lt;a href=&quot;/wiki/Special:Userlogin&quot;&gt;logged in&lt;/a&gt; -to upload files. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadtext&action=edit uploadtext]<br> -[[MediaWiki_talk:Uploadtext|Talk]] -</td><td> -&lt;strong&gt;STOP!&lt;/strong&gt; Before you upload here, -make sure to read and follow the &lt;a href=&quot;/wiki/Special:Image_use_policy&quot;&gt;image use policy&lt;/a&gt;. -&lt;p&gt;If a file with the name you are specifying already -exists on the wiki, it&#39;ll be replaced without warning. -So unless you mean to update a file, it&#39;s a good idea -to first check if such a file exists. -&lt;p&gt;To view or search previously uploaded images, -go to the &lt;a href=&quot;/wiki/Special:Imagelist&quot;&gt;list of uploaded images&lt;/a&gt;. -Uploads and deletions are logged on the &lt;a href=&quot;/wiki/Wiktionary:Upload_log&quot;&gt;upload log&lt;/a&gt;. -&lt;/p&gt;&lt;p&gt;Use the form below to upload new image files for use in -illustrating your pages. -On most browsers, you will see a &quot;Browse...&quot; button, which will -bring up your operating system&#39;s standard file open dialog. -Choosing a file will fill the name of that file into the text -field next to the button. -You must also check the box affirming that you are not -violating any copyrights by uploading the file. -Press the &quot;Upload&quot; button to finish the upload. -This may take some time if you have a slow internet connection. -&lt;p&gt;The preferred formats are JPEG for photographic images, PNG -for drawings and other iconic images, and OGG for sounds. -Please name your files descriptively to avoid confusion. -To include the image in a page, use a link in the form -&lt;b&gt;&#91;&#91;Image:file.jpg]]&lt;/b&gt; or &lt;b&gt;&#91;&#91;Image:file.png&#124;alt text]]&lt;/b&gt; -or &lt;b&gt;&#91;&#91;Media:file.ogg]]&lt;/b&gt; for sounds. -&lt;p&gt;Please note that as with wiki pages, others may edit or -delete your uploads if they think it serves the project, and -you may be blocked from uploading if you abuse the system. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadwarning&action=edit uploadwarning]<br> -[[MediaWiki_talk:Uploadwarning|Talk]] -</td><td> -Upload warning -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:User_rights_set&action=edit user_rights_set]<br> -[[MediaWiki_talk:User_rights_set|Talk]] -</td><td> -&lt;b&gt;User rights for &quot;$1&quot; updated&lt;/b&gt; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercssjs&action=edit usercssjs]<br> -[[MediaWiki_talk:Usercssjs|Talk]] -</td><td> -&#39;&#39;&#39;Note:&#39;&#39;&#39; After saving, you have to tell your bowser to get the new version: &#39;&#39;&#39;Mozilla:&#39;&#39;&#39; click &#39;&#39;reload&#39;&#39;(or &#39;&#39;ctrl-r&#39;&#39;), &#39;&#39;&#39;IE / Opera:&#39;&#39;&#39; &#39;&#39;ctrl-f5&#39;&#39;, &#39;&#39;&#39;Safari:&#39;&#39;&#39; &#39;&#39;cmd-r&#39;&#39;, &#39;&#39;&#39;Konqueror&#39;&#39;&#39; &#39;&#39;ctrl-r&#39;&#39;. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercssjsyoucanpreview&action=edit usercssjsyoucanpreview]<br> -[[MediaWiki_talk:Usercssjsyoucanpreview|Talk]] -</td><td> -&lt;strong&gt;Tip:&lt;/strong&gt; Use the &#39;Show preview&#39; button to test your new css/js before saving. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercsspreview&action=edit usercsspreview]<br> -[[MediaWiki_talk:Usercsspreview|Talk]] -</td><td> -&#39;&#39;&#39;Remember that you are only previewing your user css, it has not yet been saved!&#39;&#39;&#39; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userexists&action=edit userexists]<br> -[[MediaWiki_talk:Userexists|Talk]] -</td><td> -The user name you entered is already in use. Please choose a different name. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userjspreview&action=edit userjspreview]<br> -[[MediaWiki_talk:Userjspreview|Talk]] -</td><td> -&#39;&#39;&#39;Remember that you are only testing/previewing your user javascript, it has not yet been saved!&#39;&#39;&#39; -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userlogin&action=edit userlogin]<br> -[[MediaWiki_talk:Userlogin|Talk]] -</td><td> -Log in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userlogout&action=edit userlogout]<br> -[[MediaWiki_talk:Userlogout|Talk]] -</td><td> -Log out -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usermailererror&action=edit usermailererror]<br> -[[MediaWiki_talk:Usermailererror|Talk]] -</td><td> -Mail object returned error: -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userpage&action=edit userpage]<br> -[[MediaWiki_talk:Userpage|Talk]] -</td><td> -View user page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userstats&action=edit userstats]<br> -[[MediaWiki_talk:Userstats|Talk]] -</td><td> -User statistics -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userstatstext&action=edit userstatstext]<br> -[[MediaWiki_talk:Userstatstext|Talk]] -</td><td> -There are &#39;&#39;&#39;$1&#39;&#39;&#39; registered users. -&#39;&#39;&#39;$2&#39;&#39;&#39; of these are administrators (see $3). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Version&action=edit version]<br> -[[MediaWiki_talk:Version|Talk]] -</td><td> -Version -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewcount&action=edit viewcount]<br> -[[MediaWiki_talk:Viewcount|Talk]] -</td><td> -This page has been accessed $1 times. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewprevnext&action=edit viewprevnext]<br> -[[MediaWiki_talk:Viewprevnext|Talk]] -</td><td> -View ($1) ($2) ($3). -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewsource&action=edit viewsource]<br> -[[MediaWiki_talk:Viewsource|Talk]] -</td><td> -View source -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewtalkpage&action=edit viewtalkpage]<br> -[[MediaWiki_talk:Viewtalkpage|Talk]] -</td><td> -View discussion -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wantedpages&action=edit wantedpages]<br> -[[MediaWiki_talk:Wantedpages|Talk]] -</td><td> -Wanted pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watch&action=edit watch]<br> -[[MediaWiki_talk:Watch|Talk]] -</td><td> -Watch -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchdetails&action=edit watchdetails]<br> -[[MediaWiki_talk:Watchdetails|Talk]] -</td><td> -($1 pages watched not counting talk pages; -$2 total pages edited since cutoff; -$3... -&lt;a href=&#39;$4&#39;&gt;show and edit complete list&lt;/a&gt;.) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watcheditlist&action=edit watcheditlist]<br> -[[MediaWiki_talk:Watcheditlist|Talk]] -</td><td> -Here&#39;s an alphabetical list of your -watched pages. Check the boxes of pages you want to remove -from your watchlist and click the &#39;remove checked&#39; button -at the bottom of the screen. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlist&action=edit watchlist]<br> -[[MediaWiki_talk:Watchlist|Talk]] -</td><td> -My watchlist -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlistcontains&action=edit watchlistcontains]<br> -[[MediaWiki_talk:Watchlistcontains|Talk]] -</td><td> -Your watchlist contains $1 pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlistsub&action=edit watchlistsub]<br> -[[MediaWiki_talk:Watchlistsub|Talk]] -</td><td> -(for user &quot;$1&quot;) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchmethod-list&action=edit watchmethod-list]<br> -[[MediaWiki_talk:Watchmethod-list|Talk]] -</td><td> -checking watched pages for recent edits -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchmethod-recent&action=edit watchmethod-recent]<br> -[[MediaWiki_talk:Watchmethod-recent|Talk]] -</td><td> -checking recent edits for watched pages -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnochange&action=edit watchnochange]<br> -[[MediaWiki_talk:Watchnochange|Talk]] -</td><td> -None of your watched items were edited in the time period displayed. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnologin&action=edit watchnologin]<br> -[[MediaWiki_talk:Watchnologin|Talk]] -</td><td> -Not logged in -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnologintext&action=edit watchnologintext]<br> -[[MediaWiki_talk:Watchnologintext|Talk]] -</td><td> -You must be &lt;a href=&quot;/wiki/Special:Userlogin&quot;&gt;logged in&lt;/a&gt; -to modify your watchlist. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchthis&action=edit watchthis]<br> -[[MediaWiki_talk:Watchthis|Talk]] -</td><td> -Watch this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchthispage&action=edit watchthispage]<br> -[[MediaWiki_talk:Watchthispage|Talk]] -</td><td> -Watch this page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Welcomecreation&action=edit welcomecreation]<br> -[[MediaWiki_talk:Welcomecreation|Talk]] -</td><td> -&lt;h2&gt;Welcome, $1!&lt;/h2&gt;&lt;p&gt;Your account has been created. -Don&#39;t forget to change your Wiktionary preferences. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whatlinkshere&action=edit whatlinkshere]<br> -[[MediaWiki_talk:Whatlinkshere|Talk]] -</td><td> -What links here -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistacctext&action=edit whitelistacctext]<br> -[[MediaWiki_talk:Whitelistacctext|Talk]] -</td><td> -To be allowed to create accounts in this Wiki you have to &#91;&#91;Special:Userlogin&#124;log]] in and have the appropriate permissions. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistacctitle&action=edit whitelistacctitle]<br> -[[MediaWiki_talk:Whitelistacctitle|Talk]] -</td><td> -You are not allowed to create an account -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistedittext&action=edit whitelistedittext]<br> -[[MediaWiki_talk:Whitelistedittext|Talk]] -</td><td> -You have to &#91;&#91;Special:Userlogin&#124;login]] to edit pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistedittitle&action=edit whitelistedittitle]<br> -[[MediaWiki_talk:Whitelistedittitle|Talk]] -</td><td> -Login required to edit -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistreadtext&action=edit whitelistreadtext]<br> -[[MediaWiki_talk:Whitelistreadtext|Talk]] -</td><td> -You have to &#91;&#91;Special:Userlogin&#124;login]] to read pages. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistreadtitle&action=edit whitelistreadtitle]<br> -[[MediaWiki_talk:Whitelistreadtitle|Talk]] -</td><td> -Login required to read -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wikipediapage&action=edit wikipediapage]<br> -[[MediaWiki_talk:Wikipediapage|Talk]] -</td><td> -View project page -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wikititlesuffix&action=edit wikititlesuffix]<br> -[[MediaWiki_talk:Wikititlesuffix|Talk]] -</td><td> -Wiktionary -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlnote&action=edit wlnote]<br> -[[MediaWiki_talk:Wlnote|Talk]] -</td><td> -Below are the last $1 changes in the last &lt;b&gt;$2&lt;/b&gt; hours. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlsaved&action=edit wlsaved]<br> -[[MediaWiki_talk:Wlsaved|Talk]] -</td><td> -This is a saved version of your watchlist. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlshowlast&action=edit wlshowlast]<br> -[[MediaWiki_talk:Wlshowlast|Talk]] -</td><td> -Show last $1 hours $2 days $3 -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wrong_wfQuery_params&action=edit wrong_wfQuery_params]<br> -[[MediaWiki_talk:Wrong_wfQuery_params|Talk]] -</td><td> -Incorrect parameters to wfQuery()&lt;br /&gt; -Function: $1&lt;br /&gt; -Query: $2 - -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wrongpassword&action=edit wrongpassword]<br> -[[MediaWiki_talk:Wrongpassword|Talk]] -</td><td> -The password you entered is incorrect. Please try again. -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourdiff&action=edit yourdiff]<br> -[[MediaWiki_talk:Yourdiff|Talk]] -</td><td> -Differences -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Youremail&action=edit youremail]<br> -[[MediaWiki_talk:Youremail|Talk]] -</td><td> -Your email* -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourname&action=edit yourname]<br> -[[MediaWiki_talk:Yourname|Talk]] -</td><td> -Your user name -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yournick&action=edit yournick]<br> -[[MediaWiki_talk:Yournick|Talk]] -</td><td> -Your nickname (for signatures) -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourpassword&action=edit yourpassword]<br> -[[MediaWiki_talk:Yourpassword|Talk]] -</td><td> -Your password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourpasswordagain&action=edit yourpasswordagain]<br> -[[MediaWiki_talk:Yourpasswordagain|Talk]] -</td><td> -Retype password -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourrealname&action=edit yourrealname]<br> -[[MediaWiki_talk:Yourrealname|Talk]] -</td><td> -Your real name* -</td><td> - -</td></tr><tr><td> -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourtext&action=edit yourtext]<br> -[[MediaWiki_talk:Yourtext|Talk]] -</td><td> -Your text -</td><td> - -</td></tr></table> - - \ No newline at end of file diff --git a/tests/parser/preprocess/All_system_messages.txt b/tests/parser/preprocess/All_system_messages.txt deleted file mode 100644 index fc10d7cf..00000000 --- a/tests/parser/preprocess/All_system_messages.txt +++ /dev/null @@ -1,5645 +0,0 @@ -{{int:allmessagestext}} - -
    -'''Name''' - -'''Default text''' - -'''Current text''' -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:1movedto2&action=edit 1movedto2]
    -[[MediaWiki_talk:1movedto2|Talk]] -
    -$1 moved to $2 - -{{int:1movedto2}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Monobook.css&action=edit Monobook.css]
    -[[MediaWiki_talk:Monobook.css|Talk]] -
    -/* edit this file to customize the monobook skin for the entire site */ - -{{int:Monobook.css}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:About&action=edit about]
    -[[MediaWiki_talk:About|Talk]] -
    -About - -{{int:About}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Aboutpage&action=edit aboutpage]
    -[[MediaWiki_talk:Aboutpage|Talk]] -
    -Wiktionary:About - -{{int:Aboutpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Aboutwikipedia&action=edit aboutwikipedia]
    -[[MediaWiki_talk:Aboutwikipedia|Talk]] -
    -About Wiktionary - -{{int:Aboutwikipedia}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-addsection&action=edit accesskey-addsection]
    -[[MediaWiki_talk:Accesskey-addsection|Talk]] -
    -+ - -{{int:Accesskey-addsection}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-anontalk&action=edit accesskey-anontalk]
    -[[MediaWiki_talk:Accesskey-anontalk|Talk]] -
    -n - -{{int:Accesskey-anontalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-anonuserpage&action=edit accesskey-anonuserpage]
    -[[MediaWiki_talk:Accesskey-anonuserpage|Talk]] -
    -. - -{{int:Accesskey-anonuserpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-article&action=edit accesskey-article]
    -[[MediaWiki_talk:Accesskey-article|Talk]] -
    -a - -{{int:Accesskey-article}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-compareselectedversions&action=edit accesskey-compareselectedversions]
    -[[MediaWiki_talk:Accesskey-compareselectedversions|Talk]] -
    -v - -{{int:Accesskey-compareselectedversions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-contributions&action=edit accesskey-contributions]
    -[[MediaWiki_talk:Accesskey-contributions|Talk]] -
    -&lt;accesskey-contributions&gt; - -{{int:Accesskey-contributions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-currentevents&action=edit accesskey-currentevents]
    -[[MediaWiki_talk:Accesskey-currentevents|Talk]] -
    -&lt;accesskey-currentevents&gt; - -{{int:Accesskey-currentevents}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-delete&action=edit accesskey-delete]
    -[[MediaWiki_talk:Accesskey-delete|Talk]] -
    -d - -{{int:Accesskey-delete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-edit&action=edit accesskey-edit]
    -[[MediaWiki_talk:Accesskey-edit|Talk]] -
    -e - -{{int:Accesskey-edit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-emailuser&action=edit accesskey-emailuser]
    -[[MediaWiki_talk:Accesskey-emailuser|Talk]] -
    -&lt;accesskey-emailuser&gt; - -{{int:Accesskey-emailuser}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-help&action=edit accesskey-help]
    -[[MediaWiki_talk:Accesskey-help|Talk]] -
    -&lt;accesskey-help&gt; - -{{int:Accesskey-help}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-history&action=edit accesskey-history]
    -[[MediaWiki_talk:Accesskey-history|Talk]] -
    -h - -{{int:Accesskey-history}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-login&action=edit accesskey-login]
    -[[MediaWiki_talk:Accesskey-login|Talk]] -
    -o - -{{int:Accesskey-login}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-logout&action=edit accesskey-logout]
    -[[MediaWiki_talk:Accesskey-logout|Talk]] -
    -o - -{{int:Accesskey-logout}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mainpage&action=edit accesskey-mainpage]
    -[[MediaWiki_talk:Accesskey-mainpage|Talk]] -
    -z - -{{int:Accesskey-mainpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-minoredit&action=edit accesskey-minoredit]
    -[[MediaWiki_talk:Accesskey-minoredit|Talk]] -
    -i - -{{int:Accesskey-minoredit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-move&action=edit accesskey-move]
    -[[MediaWiki_talk:Accesskey-move|Talk]] -
    -m - -{{int:Accesskey-move}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mycontris&action=edit accesskey-mycontris]
    -[[MediaWiki_talk:Accesskey-mycontris|Talk]] -
    -y - -{{int:Accesskey-mycontris}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-mytalk&action=edit accesskey-mytalk]
    -[[MediaWiki_talk:Accesskey-mytalk|Talk]] -
    -n - -{{int:Accesskey-mytalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-portal&action=edit accesskey-portal]
    -[[MediaWiki_talk:Accesskey-portal|Talk]] -
    -&lt;accesskey-portal&gt; - -{{int:Accesskey-portal}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-preferences&action=edit accesskey-preferences]
    -[[MediaWiki_talk:Accesskey-preferences|Talk]] -
    -&lt;accesskey-preferences&gt; - -{{int:Accesskey-preferences}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-preview&action=edit accesskey-preview]
    -[[MediaWiki_talk:Accesskey-preview|Talk]] -
    -p - -{{int:Accesskey-preview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-protect&action=edit accesskey-protect]
    -[[MediaWiki_talk:Accesskey-protect|Talk]] -
    -= - -{{int:Accesskey-protect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-randompage&action=edit accesskey-randompage]
    -[[MediaWiki_talk:Accesskey-randompage|Talk]] -
    -x - -{{int:Accesskey-randompage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-recentchanges&action=edit accesskey-recentchanges]
    -[[MediaWiki_talk:Accesskey-recentchanges|Talk]] -
    -r - -{{int:Accesskey-recentchanges}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-recentchangeslinked&action=edit accesskey-recentchangeslinked]
    -[[MediaWiki_talk:Accesskey-recentchangeslinked|Talk]] -
    -c - -{{int:Accesskey-recentchangeslinked}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-save&action=edit accesskey-save]
    -[[MediaWiki_talk:Accesskey-save|Talk]] -
    -s - -{{int:Accesskey-save}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-search&action=edit accesskey-search]
    -[[MediaWiki_talk:Accesskey-search|Talk]] -
    -f - -{{int:Accesskey-search}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-sitesupport&action=edit accesskey-sitesupport]
    -[[MediaWiki_talk:Accesskey-sitesupport|Talk]] -
    -&lt;accesskey-sitesupport&gt; - -{{int:Accesskey-sitesupport}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-specialpage&action=edit accesskey-specialpage]
    -[[MediaWiki_talk:Accesskey-specialpage|Talk]] -
    -&lt;accesskey-specialpage&gt; - -{{int:Accesskey-specialpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-specialpages&action=edit accesskey-specialpages]
    -[[MediaWiki_talk:Accesskey-specialpages|Talk]] -
    -q - -{{int:Accesskey-specialpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-talk&action=edit accesskey-talk]
    -[[MediaWiki_talk:Accesskey-talk|Talk]] -
    -t - -{{int:Accesskey-talk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-undelete&action=edit accesskey-undelete]
    -[[MediaWiki_talk:Accesskey-undelete|Talk]] -
    -d - -{{int:Accesskey-undelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-unwatch&action=edit accesskey-unwatch]
    -[[MediaWiki_talk:Accesskey-unwatch|Talk]] -
    -w - -{{int:Accesskey-unwatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-upload&action=edit accesskey-upload]
    -[[MediaWiki_talk:Accesskey-upload|Talk]] -
    -u - -{{int:Accesskey-upload}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-userpage&action=edit accesskey-userpage]
    -[[MediaWiki_talk:Accesskey-userpage|Talk]] -
    -. - -{{int:Accesskey-userpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-viewsource&action=edit accesskey-viewsource]
    -[[MediaWiki_talk:Accesskey-viewsource|Talk]] -
    -e - -{{int:Accesskey-viewsource}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-watch&action=edit accesskey-watch]
    -[[MediaWiki_talk:Accesskey-watch|Talk]] -
    -w - -{{int:Accesskey-watch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-watchlist&action=edit accesskey-watchlist]
    -[[MediaWiki_talk:Accesskey-watchlist|Talk]] -
    -l - -{{int:Accesskey-watchlist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accesskey-whatlinkshere&action=edit accesskey-whatlinkshere]
    -[[MediaWiki_talk:Accesskey-whatlinkshere|Talk]] -
    -b - -{{int:Accesskey-whatlinkshere}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accmailtext&action=edit accmailtext]
    -[[MediaWiki_talk:Accmailtext|Talk]] -
    -The Password for '$1' has been sent to $2. - -{{int:Accmailtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Accmailtitle&action=edit accmailtitle]
    -[[MediaWiki_talk:Accmailtitle|Talk]] -
    -Password sent. - -{{int:Accmailtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Actioncomplete&action=edit actioncomplete]
    -[[MediaWiki_talk:Actioncomplete|Talk]] -
    -Action complete - -{{int:Actioncomplete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addedwatch&action=edit addedwatch]
    -[[MediaWiki_talk:Addedwatch|Talk]] -
    -Added to watchlist - -{{int:Addedwatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addedwatchtext&action=edit addedwatchtext]
    -[[MediaWiki_talk:Addedwatchtext|Talk]] -
    -The page "$1" has been added to your [[Special:Watchlist|watchlist]]. -Future changes to this page and its associated Talk page will be listed there, -and the page will appear '''bolded''' in the [[Special:Recentchanges|list of recent changes]] to -make it easier to pick out. - -<p>If you want to remove the page from your watchlist later, click "Stop watching" in the sidebar. - -{{int:Addedwatchtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Addsection&action=edit addsection]
    -[[MediaWiki_talk:Addsection|Talk]] -
    -+ - -{{int:Addsection}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Administrators&action=edit administrators]
    -[[MediaWiki_talk:Administrators|Talk]] -
    -Wiktionary:Administrators - -{{int:Administrators}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Affirmation&action=edit affirmation]
    -[[MediaWiki_talk:Affirmation|Talk]] -
    -I affirm that the copyright holder of this file -agrees to license it under the terms of the $1. - -{{int:Affirmation}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:All&action=edit all]
    -[[MediaWiki_talk:All|Talk]] -
    -all - -{{int:All}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allmessages&action=edit allmessages]
    -[[MediaWiki_talk:Allmessages|Talk]] -
    -All system messages - -{{int:Allmessages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allmessagestext&action=edit allmessagestext]
    -[[MediaWiki_talk:Allmessagestext|Talk]] -
    -This is a list of all system messages available in the MediaWiki: namespace. - -{{int:Allmessagestext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Allpages&action=edit allpages]
    -[[MediaWiki_talk:Allpages|Talk]] -
    -All pages - -{{int:Allpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alphaindexline&action=edit alphaindexline]
    -[[MediaWiki_talk:Alphaindexline|Talk]] -
    -$1 to $2 - -{{int:Alphaindexline}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alreadyloggedin&action=edit alreadyloggedin]
    -[[MediaWiki_talk:Alreadyloggedin|Talk]] -
    -<font color=red><b>User $1, you are already logged in!</b></font><br /> - - -{{int:Alreadyloggedin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Alreadyrolled&action=edit alreadyrolled]
    -[[MediaWiki_talk:Alreadyrolled|Talk]] -
    -Cannot rollback last edit of [[$1]] -by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the page already. - -Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]). - -{{int:Alreadyrolled}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ancientpages&action=edit ancientpages]
    -[[MediaWiki_talk:Ancientpages|Talk]] -
    -Oldest pages - -{{int:Ancientpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:And&action=edit and]
    -[[MediaWiki_talk:And|Talk]] -
    -and - -{{int:And}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anontalk&action=edit anontalk]
    -[[MediaWiki_talk:Anontalk|Talk]] -
    -Talk for this IP - -{{int:Anontalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anontalkpagetext&action=edit anontalkpagetext]
    -[[MediaWiki_talk:Anontalkpagetext|Talk]] -
    -----''This is the discussion page for an anonymous user who has not created an account yet or who does not use it. We therefore have to use the numerical [[IP address]] to identify him/her. Such an IP address can be shared by several users. If you are an anonymous user and feel that irrelevant comments have been directed at you, please [[Special:Userlogin|create an account or log in]] to avoid future confusion with other anonymous users.'' - -{{int:Anontalkpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Anonymous&action=edit anonymous]
    -[[MediaWiki_talk:Anonymous|Talk]] -
    -Anonymous user(s) of Wiktionary - -{{int:Anonymous}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Article&action=edit article]
    -[[MediaWiki_talk:Article|Talk]] -
    -Content page - -{{int:Article}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Articleexists&action=edit articleexists]
    -[[MediaWiki_talk:Articleexists|Talk]] -
    -A page of that name already exists, or the -name you have chosen is not valid. -Please choose another name. - -{{int:Articleexists}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Articlepage&action=edit articlepage]
    -[[MediaWiki_talk:Articlepage|Talk]] -
    -View content page - -{{int:Articlepage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Asksql&action=edit asksql]
    -[[MediaWiki_talk:Asksql|Talk]] -
    -SQL query - -{{int:Asksql}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Asksqltext&action=edit asksqltext]
    -[[MediaWiki_talk:Asksqltext|Talk]] -
    -Use the form below to make a direct query of the -database. -Use single quotes ('like this') to delimit string literals. -This can often add considerable load to the server, so please use -this function sparingly. - -{{int:Asksqltext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Autoblocker&action=edit autoblocker]
    -[[MediaWiki_talk:Autoblocker|Talk]] -
    -Autoblocked because you share an IP address with "$1". Reason "$2". - -{{int:Autoblocker}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badarticleerror&action=edit badarticleerror]
    -[[MediaWiki_talk:Badarticleerror|Talk]] -
    -This action cannot be performed on this page. - -{{int:Badarticleerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badfilename&action=edit badfilename]
    -[[MediaWiki_talk:Badfilename|Talk]] -
    -Image name has been changed to "$1". - -{{int:Badfilename}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badfiletype&action=edit badfiletype]
    -[[MediaWiki_talk:Badfiletype|Talk]] -
    -".$1" is not a recommended image file format. - -{{int:Badfiletype}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badipaddress&action=edit badipaddress]
    -[[MediaWiki_talk:Badipaddress|Talk]] -
    -Invalid IP address - -{{int:Badipaddress}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badquery&action=edit badquery]
    -[[MediaWiki_talk:Badquery|Talk]] -
    -Badly formed search query - -{{int:Badquery}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badquerytext&action=edit badquerytext]
    -[[MediaWiki_talk:Badquerytext|Talk]] -
    -We could not process your query. -This is probably because you have attempted to search for a -word fewer than three letters long, which is not yet supported. -It could also be that you have mistyped the expression, for -example "fish and and scales". -Please try another query. - -{{int:Badquerytext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badretype&action=edit badretype]
    -[[MediaWiki_talk:Badretype|Talk]] -
    -The passwords you entered do not match. - -{{int:Badretype}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badtitle&action=edit badtitle]
    -[[MediaWiki_talk:Badtitle|Talk]] -
    -Bad title - -{{int:Badtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Badtitletext&action=edit badtitletext]
    -[[MediaWiki_talk:Badtitletext|Talk]] -
    -The requested page title was invalid, empty, or -an incorrectly linked inter-language or inter-wiki title. - -{{int:Badtitletext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blanknamespace&action=edit blanknamespace]
    -[[MediaWiki_talk:Blanknamespace|Talk]] -
    -(Main) - -{{int:Blanknamespace}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockedtext&action=edit blockedtext]
    -[[MediaWiki_talk:Blockedtext|Talk]] -
    -Your user name or IP address has been blocked by $1. -The reason given is this:<br />''$2''<p>You may contact $1 or one of the other -[[Wiktionary:Administrators|administrators]] to discuss the block. - -Note that you may not use the "email this user" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]]. - -Your IP address is $3. Please include this address in any queries you make. - - -{{int:Blockedtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockedtitle&action=edit blockedtitle]
    -[[MediaWiki_talk:Blockedtitle|Talk]] -
    -User is blocked - -{{int:Blockedtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockip&action=edit blockip]
    -[[MediaWiki_talk:Blockip|Talk]] -
    -Block user - -{{int:Blockip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockipsuccesssub&action=edit blockipsuccesssub]
    -[[MediaWiki_talk:Blockipsuccesssub|Talk]] -
    -Block succeeded - -{{int:Blockipsuccesssub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockipsuccesstext&action=edit blockipsuccesstext]
    -[[MediaWiki_talk:Blockipsuccesstext|Talk]] -
    -"$1" has been blocked. -<br />See [[Special:Ipblocklist|IP block list]] to review blocks. - -{{int:Blockipsuccesstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blockiptext&action=edit blockiptext]
    -[[MediaWiki_talk:Blockiptext|Talk]] -
    -Use the form below to block write access -from a specific IP address or username. -This should be done only only to prevent vandalism, and in -accordance with [[Wiktionary:Policy|policy]]. -Fill in a specific reason below (for example, citing particular -pages that were vandalized). - -{{int:Blockiptext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklink&action=edit blocklink]
    -[[MediaWiki_talk:Blocklink|Talk]] -
    -block - -{{int:Blocklink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklistline&action=edit blocklistline]
    -[[MediaWiki_talk:Blocklistline|Talk]] -
    -$1, $2 blocked $3 (expires $4) - -{{int:Blocklistline}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogentry&action=edit blocklogentry]
    -[[MediaWiki_talk:Blocklogentry|Talk]] -
    -blocked "$1" with an expiry time of $2 - -{{int:Blocklogentry}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogpage&action=edit blocklogpage]
    -[[MediaWiki_talk:Blocklogpage|Talk]] -
    -Block_log - -{{int:Blocklogpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Blocklogtext&action=edit blocklogtext]
    -[[MediaWiki_talk:Blocklogtext|Talk]] -
    -This is a log of user blocking and unblocking actions. Automatically -blocked IP addresses are not be listed. See the [[Special:Ipblocklist|IP block list]] for -the list of currently operational bans and blocks. - -{{int:Blocklogtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bold_sample&action=edit bold_sample]
    -[[MediaWiki_talk:Bold_sample|Talk]] -
    -Bold text - -{{int:Bold_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bold_tip&action=edit bold_tip]
    -[[MediaWiki_talk:Bold_tip|Talk]] -
    -Bold text - -{{int:Bold_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Booksources&action=edit booksources]
    -[[MediaWiki_talk:Booksources|Talk]] -
    -Book sources - -{{int:Booksources}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Booksourcetext&action=edit booksourcetext]
    -[[MediaWiki_talk:Booksourcetext|Talk]] -
    -Below is a list of links to other sites that -sell new and used books, and may also have further information -about books you are looking for.Wiktionary is not affiliated with any of these businesses, and -this list should not be construed as an endorsement. - -{{int:Booksourcetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Brokenredirects&action=edit brokenredirects]
    -[[MediaWiki_talk:Brokenredirects|Talk]] -
    -Broken Redirects - -{{int:Brokenredirects}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Brokenredirectstext&action=edit brokenredirectstext]
    -[[MediaWiki_talk:Brokenredirectstext|Talk]] -
    -The following redirects link to a non-existing pages. - -{{int:Brokenredirectstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bugreports&action=edit bugreports]
    -[[MediaWiki_talk:Bugreports|Talk]] -
    -Bug reports - -{{int:Bugreports}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bugreportspage&action=edit bugreportspage]
    -[[MediaWiki_talk:Bugreportspage|Talk]] -
    -Wiktionary:Bug_reports - -{{int:Bugreportspage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucratlog&action=edit bureaucratlog]
    -[[MediaWiki_talk:Bureaucratlog|Talk]] -
    -Bureaucrat_log - -{{int:Bureaucratlog}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucratlogentry&action=edit bureaucratlogentry]
    -[[MediaWiki_talk:Bureaucratlogentry|Talk]] -
    -Rights for user "$1" set "$2" - -{{int:Bureaucratlogentry}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucrattext&action=edit bureaucrattext]
    -[[MediaWiki_talk:Bureaucrattext|Talk]] -
    -The action you have requested can only be -performed by sysops with "bureaucrat" status. - -{{int:Bureaucrattext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bureaucrattitle&action=edit bureaucrattitle]
    -[[MediaWiki_talk:Bureaucrattitle|Talk]] -
    -Bureaucrat access required - -{{int:Bureaucrattitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bydate&action=edit bydate]
    -[[MediaWiki_talk:Bydate|Talk]] -
    -by date - -{{int:Bydate}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Byname&action=edit byname]
    -[[MediaWiki_talk:Byname|Talk]] -
    -by name - -{{int:Byname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Bysize&action=edit bysize]
    -[[MediaWiki_talk:Bysize|Talk]] -
    -by size - -{{int:Bysize}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cachederror&action=edit cachederror]
    -[[MediaWiki_talk:Cachederror|Talk]] -
    -The following is a cached copy of the requested page, and may not be up to date. - -{{int:Cachederror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cancel&action=edit cancel]
    -[[MediaWiki_talk:Cancel|Talk]] -
    -Cancel - -{{int:Cancel}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cannotdelete&action=edit cannotdelete]
    -[[MediaWiki_talk:Cannotdelete|Talk]] -
    -Could not delete the page or image specified. (It may have already been deleted by someone else.) - -{{int:Cannotdelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cantrollback&action=edit cantrollback]
    -[[MediaWiki_talk:Cantrollback|Talk]] -
    -Cannot revert edit; last contributor is only author of this page. - -{{int:Cantrollback}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Categories&action=edit categories]
    -[[MediaWiki_talk:Categories|Talk]] -
    -Categories - -{{int:Categories}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Category&action=edit category]
    -[[MediaWiki_talk:Category|Talk]] -
    -category - -{{int:Category}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Category_header&action=edit category_header]
    -[[MediaWiki_talk:Category_header|Talk]] -
    -Articles in category "$1" - -{{int:Category_header}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Changepassword&action=edit changepassword]
    -[[MediaWiki_talk:Changepassword|Talk]] -
    -Change password - -{{int:Changepassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Changes&action=edit changes]
    -[[MediaWiki_talk:Changes|Talk]] -
    -changes - -{{int:Changes}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Columns&action=edit columns]
    -[[MediaWiki_talk:Columns|Talk]] -
    -Columns - -{{int:Columns}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Commentedit&action=edit commentedit]
    -[[MediaWiki_talk:Commentedit|Talk]] -
    - (comment) - -{{int:Commentedit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Compareselectedversions&action=edit compareselectedversions]
    -[[MediaWiki_talk:Compareselectedversions|Talk]] -
    -Compare selected versions - -{{int:Compareselectedversions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirm&action=edit confirm]
    -[[MediaWiki_talk:Confirm|Talk]] -
    -Confirm - -{{int:Confirm}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmcheck&action=edit confirmcheck]
    -[[MediaWiki_talk:Confirmcheck|Talk]] -
    -Yes, I really want to delete this. - -{{int:Confirmcheck}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmdelete&action=edit confirmdelete]
    -[[MediaWiki_talk:Confirmdelete|Talk]] -
    -Confirm delete - -{{int:Confirmdelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmdeletetext&action=edit confirmdeletetext]
    -[[MediaWiki_talk:Confirmdeletetext|Talk]] -
    -You are about to permanently delete a page -or image along with all of its history from the database. -Please confirm that you intend to do this, that you understand the -consequences, and that you are doing this in accordance with -[[Wiktionary:Policy]]. - -{{int:Confirmdeletetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmprotect&action=edit confirmprotect]
    -[[MediaWiki_talk:Confirmprotect|Talk]] -
    -Confirm protection - -{{int:Confirmprotect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmprotecttext&action=edit confirmprotecttext]
    -[[MediaWiki_talk:Confirmprotecttext|Talk]] -
    -Do you really want to protect this page? - -{{int:Confirmprotecttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmunprotect&action=edit confirmunprotect]
    -[[MediaWiki_talk:Confirmunprotect|Talk]] -
    -Confirm unprotection - -{{int:Confirmunprotect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Confirmunprotecttext&action=edit confirmunprotecttext]
    -[[MediaWiki_talk:Confirmunprotecttext|Talk]] -
    -Do you really want to unprotect this page? - -{{int:Confirmunprotecttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contextchars&action=edit contextchars]
    -[[MediaWiki_talk:Contextchars|Talk]] -
    -Characters of context per line - -{{int:Contextchars}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contextlines&action=edit contextlines]
    -[[MediaWiki_talk:Contextlines|Talk]] -
    -Lines to show per hit - -{{int:Contextlines}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contribslink&action=edit contribslink]
    -[[MediaWiki_talk:Contribslink|Talk]] -
    -contribs - -{{int:Contribslink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contribsub&action=edit contribsub]
    -[[MediaWiki_talk:Contribsub|Talk]] -
    -For $1 - -{{int:Contribsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Contributions&action=edit contributions]
    -[[MediaWiki_talk:Contributions|Talk]] -
    -User contributions - -{{int:Contributions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyright&action=edit copyright]
    -[[MediaWiki_talk:Copyright|Talk]] -
    -Content is available under $1. - -{{int:Copyright}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightpage&action=edit copyrightpage]
    -[[MediaWiki_talk:Copyrightpage|Talk]] -
    -Wiktionary:Copyrights - -{{int:Copyrightpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightpagename&action=edit copyrightpagename]
    -[[MediaWiki_talk:Copyrightpagename|Talk]] -
    -Wiktionary copyright - -{{int:Copyrightpagename}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Copyrightwarning&action=edit copyrightwarning]
    -[[MediaWiki_talk:Copyrightwarning|Talk]] -
    -Please note that all contributions to Wiktionary are -considered to be released under the GNU Free Documentation License -(see $1 for details). -If you don't want your writing to be edited mercilessly and redistributed -at will, then don't submit it here.<br /> -You are also promising us that you wrote this yourself, or copied it from a -public domain or similar free resource. -<strong>DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!</strong> - -{{int:Copyrightwarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Couldntremove&action=edit couldntremove]
    -[[MediaWiki_talk:Couldntremove|Talk]] -
    -Couldn't remove item '$1'... - -{{int:Couldntremove}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Createaccount&action=edit createaccount]
    -[[MediaWiki_talk:Createaccount|Talk]] -
    -Create new account - -{{int:Createaccount}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Createaccountmail&action=edit createaccountmail]
    -[[MediaWiki_talk:Createaccountmail|Talk]] -
    -by email - -{{int:Createaccountmail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Cur&action=edit cur]
    -[[MediaWiki_talk:Cur|Talk]] -
    -cur - -{{int:Cur}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Currentevents&action=edit currentevents]
    -[[MediaWiki_talk:Currentevents|Talk]] -
    -Current events - -{{int:Currentevents}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Currentrev&action=edit currentrev]
    -[[MediaWiki_talk:Currentrev|Talk]] -
    -Current revision - -{{int:Currentrev}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Databaseerror&action=edit databaseerror]
    -[[MediaWiki_talk:Databaseerror|Talk]] -
    -Database error - -{{int:Databaseerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dateformat&action=edit dateformat]
    -[[MediaWiki_talk:Dateformat|Talk]] -
    -Date format - -{{int:Dateformat}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dberrortext&action=edit dberrortext]
    -[[MediaWiki_talk:Dberrortext|Talk]] -
    -A database query syntax error has occurred. -This could be because of an illegal search query (see $5), -or it may indicate a bug in the software. -The last attempted database query was: -<blockquote><tt>$1</tt></blockquote> -from within function "<tt>$2</tt>". -MySQL returned error "<tt>$3: $4</tt>". - -{{int:Dberrortext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dberrortextcl&action=edit dberrortextcl]
    -[[MediaWiki_talk:Dberrortextcl|Talk]] -
    -A database query syntax error has occurred. -The last attempted database query was: -"$1" -from within function "$2". -MySQL returned error "$3: $4". - - -{{int:Dberrortextcl}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deadendpages&action=edit deadendpages]
    -[[MediaWiki_talk:Deadendpages|Talk]] -
    -Dead-end pages - -{{int:Deadendpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Debug&action=edit debug]
    -[[MediaWiki_talk:Debug|Talk]] -
    -Debug - -{{int:Debug}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Defaultns&action=edit defaultns]
    -[[MediaWiki_talk:Defaultns|Talk]] -
    -Search in these namespaces by default: - -{{int:Defaultns}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Defemailsubject&action=edit defemailsubject]
    -[[MediaWiki_talk:Defemailsubject|Talk]] -
    -Wiktionary e-mail - -{{int:Defemailsubject}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Delete&action=edit delete]
    -[[MediaWiki_talk:Delete|Talk]] -
    -Delete - -{{int:Delete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletecomment&action=edit deletecomment]
    -[[MediaWiki_talk:Deletecomment|Talk]] -
    -Reason for deletion - -{{int:Deletecomment}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletedarticle&action=edit deletedarticle]
    -[[MediaWiki_talk:Deletedarticle|Talk]] -
    -deleted "$1" - -{{int:Deletedarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletedtext&action=edit deletedtext]
    -[[MediaWiki_talk:Deletedtext|Talk]] -
    -"$1" has been deleted. -See $2 for a record of recent deletions. - -{{int:Deletedtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deleteimg&action=edit deleteimg]
    -[[MediaWiki_talk:Deleteimg|Talk]] -
    -del - -{{int:Deleteimg}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletepage&action=edit deletepage]
    -[[MediaWiki_talk:Deletepage|Talk]] -
    -Delete page - -{{int:Deletepage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletesub&action=edit deletesub]
    -[[MediaWiki_talk:Deletesub|Talk]] -
    -(Deleting "$1") - -{{int:Deletesub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletethispage&action=edit deletethispage]
    -[[MediaWiki_talk:Deletethispage|Talk]] -
    -Delete this page - -{{int:Deletethispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Deletionlog&action=edit deletionlog]
    -[[MediaWiki_talk:Deletionlog|Talk]] -
    -deletion log - -{{int:Deletionlog}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dellogpage&action=edit dellogpage]
    -[[MediaWiki_talk:Dellogpage|Talk]] -
    -Deletion_log - -{{int:Dellogpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Dellogpagetext&action=edit dellogpagetext]
    -[[MediaWiki_talk:Dellogpagetext|Talk]] -
    -Below is a list of the most recent deletions. -All times shown are server time (UTC). -<ul> -</ul> - - -{{int:Dellogpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developerspheading&action=edit developerspheading]
    -[[MediaWiki_talk:Developerspheading|Talk]] -
    -For developer use only - -{{int:Developerspheading}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developertext&action=edit developertext]
    -[[MediaWiki_talk:Developertext|Talk]] -
    -The action you have requested can only be -performed by users with "developer" status. -See $1. - -{{int:Developertext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Developertitle&action=edit developertitle]
    -[[MediaWiki_talk:Developertitle|Talk]] -
    -Developer access required - -{{int:Developertitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Diff&action=edit diff]
    -[[MediaWiki_talk:Diff|Talk]] -
    -diff - -{{int:Diff}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Difference&action=edit difference]
    -[[MediaWiki_talk:Difference|Talk]] -
    -(Difference between revisions) - -{{int:Difference}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguations&action=edit disambiguations]
    -[[MediaWiki_talk:Disambiguations|Talk]] -
    -Disambiguation pages - -{{int:Disambiguations}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationspage&action=edit disambiguationspage]
    -[[MediaWiki_talk:Disambiguationspage|Talk]] -
    -Wiktionary:Links_to_disambiguating_pages - -{{int:Disambiguationspage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disambiguationstext&action=edit disambiguationstext]
    -[[MediaWiki_talk:Disambiguationstext|Talk]] -
    -The following pages link to a <i>disambiguation page</i>. They should link to the appropriate topic instead.<br />A page is treated as dismbiguation if it is linked from $1.<br />Links from other namespaces are <i>not</i> listed here. - -{{int:Disambiguationstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]
    -[[MediaWiki_talk:Disclaimerpage|Talk]] -
    -Wiktionary:General_disclaimer - -{{int:Disclaimerpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimers&action=edit disclaimers]
    -[[MediaWiki_talk:Disclaimers|Talk]] -
    -Disclaimers - -{{int:Disclaimers}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Doubleredirects&action=edit doubleredirects]
    -[[MediaWiki_talk:Doubleredirects|Talk]] -
    -Double Redirects - -{{int:Doubleredirects}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Doubleredirectstext&action=edit doubleredirectstext]
    -[[MediaWiki_talk:Doubleredirectstext|Talk]] -
    -<b>Attention:</b> This list may contain false positives. That usually means there is additional text with links below the first #REDIRECT.<br /> -Each row contains links to the first and second redirect, as well as the first line of the second redirect text, usually giving the "real" target page, which the first redirect should point to. - -{{int:Doubleredirectstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edit&action=edit edit]
    -[[MediaWiki_talk:Edit|Talk]] -
    -Edit - -{{int:Edit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editcomment&action=edit editcomment]
    -[[MediaWiki_talk:Editcomment|Talk]] -
    -The edit comment was: "<i>$1</i>". - -{{int:Editcomment}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editconflict&action=edit editconflict]
    -[[MediaWiki_talk:Editconflict|Talk]] -
    -Edit conflict: $1 - -{{int:Editconflict}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editcurrent&action=edit editcurrent]
    -[[MediaWiki_talk:Editcurrent|Talk]] -
    -Edit the current version of this page - -{{int:Editcurrent}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edithelp&action=edit edithelp]
    -[[MediaWiki_talk:Edithelp|Talk]] -
    -Editing help - -{{int:Edithelp}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Edithelppage&action=edit edithelppage]
    -[[MediaWiki_talk:Edithelppage|Talk]] -
    -Help:Editing - -{{int:Edithelppage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editing&action=edit editing]
    -[[MediaWiki_talk:Editing|Talk]] -
    -Editing $1 - -{{int:Editing}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editingold&action=edit editingold]
    -[[MediaWiki_talk:Editingold|Talk]] -
    -<strong>WARNING: You are editing an out-of-date -revision of this page. -If you save it, any changes made since this revision will be lost.</strong> - - -{{int:Editingold}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editsection&action=edit editsection]
    -[[MediaWiki_talk:Editsection|Talk]] -
    -edit - -{{int:Editsection}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Editthispage&action=edit editthispage]
    -[[MediaWiki_talk:Editthispage|Talk]] -
    -Edit this page - -{{int:Editthispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailflag&action=edit emailflag]
    -[[MediaWiki_talk:Emailflag|Talk]] -
    -Disable e-mail from other users - -{{int:Emailflag}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailforlost&action=edit emailforlost]
    -[[MediaWiki_talk:Emailforlost|Talk]] -
    -Fields marked with a star (*) are optional. Storing an email address enables people to contact you through the website without you having to reveal your -email address to them, and it can be used to send you a new password if you forget it.<br /><br />Your real name, if you choose to provide it, will be used for giving you attribution for your work. - -{{int:Emailforlost}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailfrom&action=edit emailfrom]
    -[[MediaWiki_talk:Emailfrom|Talk]] -
    -From - -{{int:Emailfrom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailmessage&action=edit emailmessage]
    -[[MediaWiki_talk:Emailmessage|Talk]] -
    -Message - -{{int:Emailmessage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpage&action=edit emailpage]
    -[[MediaWiki_talk:Emailpage|Talk]] -
    -E-mail user - -{{int:Emailpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailpagetext&action=edit emailpagetext]
    -[[MediaWiki_talk:Emailpagetext|Talk]] -
    -If this user has entered a valid e-mail address in -his or her user preferences, the form below will send a single message. -The e-mail address you entered in your user preferences will appear -as the "From" address of the mail, so the recipient will be able -to reply. - -{{int:Emailpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsend&action=edit emailsend]
    -[[MediaWiki_talk:Emailsend|Talk]] -
    -Send - -{{int:Emailsend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsent&action=edit emailsent]
    -[[MediaWiki_talk:Emailsent|Talk]] -
    -E-mail sent - -{{int:Emailsent}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsenttext&action=edit emailsenttext]
    -[[MediaWiki_talk:Emailsenttext|Talk]] -
    -Your e-mail message has been sent. - -{{int:Emailsenttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailsubject&action=edit emailsubject]
    -[[MediaWiki_talk:Emailsubject|Talk]] -
    -Subject - -{{int:Emailsubject}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailto&action=edit emailto]
    -[[MediaWiki_talk:Emailto|Talk]] -
    -To - -{{int:Emailto}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Emailuser&action=edit emailuser]
    -[[MediaWiki_talk:Emailuser|Talk]] -
    -E-mail this user - -{{int:Emailuser}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Enterlockreason&action=edit enterlockreason]
    -[[MediaWiki_talk:Enterlockreason|Talk]] -
    -Enter a reason for the lock, including an estimate -of when the lock will be released - -{{int:Enterlockreason}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Error&action=edit error]
    -[[MediaWiki_talk:Error|Talk]] -
    -Error - -{{int:Error}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Errorpagetitle&action=edit errorpagetitle]
    -[[MediaWiki_talk:Errorpagetitle|Talk]] -
    -Error - -{{int:Errorpagetitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exbeforeblank&action=edit exbeforeblank]
    -[[MediaWiki_talk:Exbeforeblank|Talk]] -
    -content before blanking was: - -{{int:Exbeforeblank}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exblank&action=edit exblank]
    -[[MediaWiki_talk:Exblank|Talk]] -
    -page was empty - -{{int:Exblank}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Excontent&action=edit excontent]
    -[[MediaWiki_talk:Excontent|Talk]] -
    -content was: - -{{int:Excontent}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Explainconflict&action=edit explainconflict]
    -[[MediaWiki_talk:Explainconflict|Talk]] -
    -Someone else has changed this page since you -started editing it. -The upper text area contains the page text as it currently exists. -Your changes are shown in the lower text area. -You will have to merge your changes into the existing text. -<b>Only</b> the text in the upper text area will be saved when you -press "Save page". -<p> - -{{int:Explainconflict}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Export&action=edit export]
    -[[MediaWiki_talk:Export|Talk]] -
    -Export pages - -{{int:Export}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exportcuronly&action=edit exportcuronly]
    -[[MediaWiki_talk:Exportcuronly|Talk]] -
    -Include only the current revision, not the full history - -{{int:Exportcuronly}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Exporttext&action=edit exporttext]
    -[[MediaWiki_talk:Exporttext|Talk]] -
    -You can export the text and editing history of a particular -page or set of pages wrapped in some XML; this can then be imported into another -wiki running MediaWiki software, transformed, or just kept for your private -amusement. - -{{int:Exporttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Extlink_sample&action=edit extlink_sample]
    -[[MediaWiki_talk:Extlink_sample|Talk]] -
    -http://www.example.com link title - -{{int:Extlink_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Extlink_tip&action=edit extlink_tip]
    -[[MediaWiki_talk:Extlink_tip|Talk]] -
    -External link (remember http:// prefix) - -{{int:Extlink_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Faq&action=edit faq]
    -[[MediaWiki_talk:Faq|Talk]] -
    -FAQ - -{{int:Faq}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Faqpage&action=edit faqpage]
    -[[MediaWiki_talk:Faqpage|Talk]] -
    -Wiktionary:FAQ - -{{int:Faqpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Feedlinks&action=edit feedlinks]
    -[[MediaWiki_talk:Feedlinks|Talk]] -
    -Feed: - -{{int:Feedlinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filecopyerror&action=edit filecopyerror]
    -[[MediaWiki_talk:Filecopyerror|Talk]] -
    -Could not copy file "$1" to "$2". - -{{int:Filecopyerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filedeleteerror&action=edit filedeleteerror]
    -[[MediaWiki_talk:Filedeleteerror|Talk]] -
    -Could not delete file "$1". - -{{int:Filedeleteerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filedesc&action=edit filedesc]
    -[[MediaWiki_talk:Filedesc|Talk]] -
    -Summary - -{{int:Filedesc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filename&action=edit filename]
    -[[MediaWiki_talk:Filename|Talk]] -
    -Filename - -{{int:Filename}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filenotfound&action=edit filenotfound]
    -[[MediaWiki_talk:Filenotfound|Talk]] -
    -Could not find file "$1". - -{{int:Filenotfound}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filerenameerror&action=edit filerenameerror]
    -[[MediaWiki_talk:Filerenameerror|Talk]] -
    -Could not rename file "$1" to "$2". - -{{int:Filerenameerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filesource&action=edit filesource]
    -[[MediaWiki_talk:Filesource|Talk]] -
    -Source - -{{int:Filesource}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Filestatus&action=edit filestatus]
    -[[MediaWiki_talk:Filestatus|Talk]] -
    -Copyright status - -{{int:Filestatus}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Fileuploaded&action=edit fileuploaded]
    -[[MediaWiki_talk:Fileuploaded|Talk]] -
    -File "$1" uploaded successfully. -Please follow this link: $2 to the description page and fill -in information about the file, such as where it came from, when it was -created and by whom, and anything else you may know about it. - -{{int:Fileuploaded}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Formerror&action=edit formerror]
    -[[MediaWiki_talk:Formerror|Talk]] -
    -Error: could not submit form - -{{int:Formerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Fromwikipedia&action=edit fromwikipedia]
    -[[MediaWiki_talk:Fromwikipedia|Talk]] -
    -From Wiktionary - -{{int:Fromwikipedia}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Getimagelist&action=edit getimagelist]
    -[[MediaWiki_talk:Getimagelist|Talk]] -
    -fetching image list - -{{int:Getimagelist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Go&action=edit go]
    -[[MediaWiki_talk:Go|Talk]] -
    -Go - -{{int:Go}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Googlesearch&action=edit googlesearch]
    -[[MediaWiki_talk:Googlesearch|Talk]] -
    - -<!-- SiteSearch Google --> -<FORM method=GET action="http://www.google.com/search"> -<TABLE bgcolor="#FFFFFF"><tr><td> -<A HREF="http://www.google.com/"> -<IMG SRC="http://www.google.com/logos/Logo_40wht.gif" -border="0" ALT="Google"></A> -</td> -<td> -<INPUT TYPE=text name=q size=31 maxlength=255 value="$1"> -<INPUT type=submit name=btnG VALUE="Google Search"> -<font size=-1> -<input type=hidden name=domains value="http://tl.wiktionary.org"><br /><input type=radio name=sitesearch value=""> WWW <input type=radio name=sitesearch value="http://tl.wiktionary.org" checked> http://tl.wiktionary.org <br /> -<input type='hidden' name='ie' value='$2'> -<input type='hidden' name='oe' value='$2'> -</font> -</td></tr></TABLE> -</FORM> -<!-- SiteSearch Google --> - -{{int:Googlesearch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Guesstimezone&action=edit guesstimezone]
    -[[MediaWiki_talk:Guesstimezone|Talk]] -
    -Fill in from browser - -{{int:Guesstimezone}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Headline_sample&action=edit headline_sample]
    -[[MediaWiki_talk:Headline_sample|Talk]] -
    -Headline text - -{{int:Headline_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Headline_tip&action=edit headline_tip]
    -[[MediaWiki_talk:Headline_tip|Talk]] -
    -Level 2 headline - -{{int:Headline_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Help&action=edit help]
    -[[MediaWiki_talk:Help|Talk]] -
    -Help - -{{int:Help}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Helppage&action=edit helppage]
    -[[MediaWiki_talk:Helppage|Talk]] -
    -Help:Contents - -{{int:Helppage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hide&action=edit hide]
    -[[MediaWiki_talk:Hide|Talk]] -
    -hide - -{{int:Hide}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hidetoc&action=edit hidetoc]
    -[[MediaWiki_talk:Hidetoc|Talk]] -
    -hide - -{{int:Hidetoc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hist&action=edit hist]
    -[[MediaWiki_talk:Hist|Talk]] -
    -hist - -{{int:Hist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Histlegend&action=edit histlegend]
    -[[MediaWiki_talk:Histlegend|Talk]] -
    -Diff selection: mark the radio boxes of the versions to compare and hit enter or the button at the bottom.<br/> -Legend: (cur) = difference with current version, -(last) = difference with preceding version, M = minor edit. - -{{int:Histlegend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:History&action=edit history]
    -[[MediaWiki_talk:History|Talk]] -
    -Page history - -{{int:History}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:History_short&action=edit history_short]
    -[[MediaWiki_talk:History_short|Talk]] -
    -History - -{{int:History_short}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Historywarning&action=edit historywarning]
    -[[MediaWiki_talk:Historywarning|Talk]] -
    -Warning: The page you are about to delete has a history: - -{{int:Historywarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Hr_tip&action=edit hr_tip]
    -[[MediaWiki_talk:Hr_tip|Talk]] -
    -Horizontal line (use sparingly) - -{{int:Hr_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ignorewarning&action=edit ignorewarning]
    -[[MediaWiki_talk:Ignorewarning|Talk]] -
    -Ignore warning and save file anyway. - -{{int:Ignorewarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ilshowmatch&action=edit ilshowmatch]
    -[[MediaWiki_talk:Ilshowmatch|Talk]] -
    -Show all images with names matching - -{{int:Ilshowmatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ilsubmit&action=edit ilsubmit]
    -[[MediaWiki_talk:Ilsubmit|Talk]] -
    -Search - -{{int:Ilsubmit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Image_sample&action=edit image_sample]
    -[[MediaWiki_talk:Image_sample|Talk]] -
    -Example.jpg - -{{int:Image_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Image_tip&action=edit image_tip]
    -[[MediaWiki_talk:Image_tip|Talk]] -
    -Embedded image - -{{int:Image_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelinks&action=edit imagelinks]
    -[[MediaWiki_talk:Imagelinks|Talk]] -
    -Image links - -{{int:Imagelinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelist&action=edit imagelist]
    -[[MediaWiki_talk:Imagelist|Talk]] -
    -Image list - -{{int:Imagelist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagelisttext&action=edit imagelisttext]
    -[[MediaWiki_talk:Imagelisttext|Talk]] -
    -Below is a list of $1 images sorted $2. - -{{int:Imagelisttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagepage&action=edit imagepage]
    -[[MediaWiki_talk:Imagepage|Talk]] -
    -View image page - -{{int:Imagepage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imagereverted&action=edit imagereverted]
    -[[MediaWiki_talk:Imagereverted|Talk]] -
    -Revert to earlier version was successful. - -{{int:Imagereverted}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imgdelete&action=edit imgdelete]
    -[[MediaWiki_talk:Imgdelete|Talk]] -
    -del - -{{int:Imgdelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imgdesc&action=edit imgdesc]
    -[[MediaWiki_talk:Imgdesc|Talk]] -
    -desc - -{{int:Imgdesc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imghistlegend&action=edit imghistlegend]
    -[[MediaWiki_talk:Imghistlegend|Talk]] -
    -Legend: (cur) = this is the current image, (del) = delete -this old version, (rev) = revert to this old version. -<br /><i>Click on date to see image uploaded on that date</i>. - -{{int:Imghistlegend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imghistory&action=edit imghistory]
    -[[MediaWiki_talk:Imghistory|Talk]] -
    -Image history - -{{int:Imghistory}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Imglegend&action=edit imglegend]
    -[[MediaWiki_talk:Imglegend|Talk]] -
    -Legend: (desc) = show/edit image description. - -{{int:Imglegend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Import&action=edit import]
    -[[MediaWiki_talk:Import|Talk]] -
    -Import pages - -{{int:Import}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importfailed&action=edit importfailed]
    -[[MediaWiki_talk:Importfailed|Talk]] -
    -Import failed: $1 - -{{int:Importfailed}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importhistoryconflict&action=edit importhistoryconflict]
    -[[MediaWiki_talk:Importhistoryconflict|Talk]] -
    -Conflicting history revision exists (may have imported this page before) - -{{int:Importhistoryconflict}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importnotext&action=edit importnotext]
    -[[MediaWiki_talk:Importnotext|Talk]] -
    -Empty or no text - -{{int:Importnotext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importsuccess&action=edit importsuccess]
    -[[MediaWiki_talk:Importsuccess|Talk]] -
    -Import succeeded! - -{{int:Importsuccess}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Importtext&action=edit importtext]
    -[[MediaWiki_talk:Importtext|Talk]] -
    -Please export the file from the source wiki using the Special:Export utility, save it to your disk and upload it here. - -{{int:Importtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Infobox&action=edit infobox]
    -[[MediaWiki_talk:Infobox|Talk]] -
    -Click a button to get an example text - -{{int:Infobox}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Infobox_alert&action=edit infobox_alert]
    -[[MediaWiki_talk:Infobox_alert|Talk]] -
    -Please enter the text you want to be formatted.\n It will be shown in the infobox for copy and pasting.\nExample:\n$1\nwill become:\n$2 - -{{int:Infobox_alert}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Internalerror&action=edit internalerror]
    -[[MediaWiki_talk:Internalerror|Talk]] -
    -Internal error - -{{int:Internalerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Intl&action=edit intl]
    -[[MediaWiki_talk:Intl|Talk]] -
    -Interlanguage links - -{{int:Intl}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ip_range_invalid&action=edit ip_range_invalid]
    -[[MediaWiki_talk:Ip_range_invalid|Talk]] -
    -Invalid IP range. - - -{{int:Ip_range_invalid}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipaddress&action=edit ipaddress]
    -[[MediaWiki_talk:Ipaddress|Talk]] -
    -IP Address/username - -{{int:Ipaddress}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipb_expiry_invalid&action=edit ipb_expiry_invalid]
    -[[MediaWiki_talk:Ipb_expiry_invalid|Talk]] -
    -Expiry time invalid. - -{{int:Ipb_expiry_invalid}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbexpiry&action=edit ipbexpiry]
    -[[MediaWiki_talk:Ipbexpiry|Talk]] -
    -Expiry - -{{int:Ipbexpiry}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipblocklist&action=edit ipblocklist]
    -[[MediaWiki_talk:Ipblocklist|Talk]] -
    -List of blocked IP addresses and usernames - -{{int:Ipblocklist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbreason&action=edit ipbreason]
    -[[MediaWiki_talk:Ipbreason|Talk]] -
    -Reason - -{{int:Ipbreason}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipbsubmit&action=edit ipbsubmit]
    -[[MediaWiki_talk:Ipbsubmit|Talk]] -
    -Block this user - -{{int:Ipbsubmit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipusubmit&action=edit ipusubmit]
    -[[MediaWiki_talk:Ipusubmit|Talk]] -
    -Unblock this address - -{{int:Ipusubmit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ipusuccess&action=edit ipusuccess]
    -[[MediaWiki_talk:Ipusuccess|Talk]] -
    -"$1" unblocked - -{{int:Ipusuccess}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Isbn&action=edit isbn]
    -[[MediaWiki_talk:Isbn|Talk]] -
    -ISBN - -{{int:Isbn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Isredirect&action=edit isredirect]
    -[[MediaWiki_talk:Isredirect|Talk]] -
    -redirect page - -{{int:Isredirect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Italic_sample&action=edit italic_sample]
    -[[MediaWiki_talk:Italic_sample|Talk]] -
    -Italic text - -{{int:Italic_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Italic_tip&action=edit italic_tip]
    -[[MediaWiki_talk:Italic_tip|Talk]] -
    -Italic text - -{{int:Italic_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Iteminvalidname&action=edit iteminvalidname]
    -[[MediaWiki_talk:Iteminvalidname|Talk]] -
    -Problem with item '$1', invalid name... - -{{int:Iteminvalidname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Largefile&action=edit largefile]
    -[[MediaWiki_talk:Largefile|Talk]] -
    -It is recommended that images not exceed 100k in size. - -{{int:Largefile}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Last&action=edit last]
    -[[MediaWiki_talk:Last|Talk]] -
    -last - -{{int:Last}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lastmodified&action=edit lastmodified]
    -[[MediaWiki_talk:Lastmodified|Talk]] -
    -This page was last modified $1. - -{{int:Lastmodified}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lastmodifiedby&action=edit lastmodifiedby]
    -[[MediaWiki_talk:Lastmodifiedby|Talk]] -
    -This page was last modified $1 by $2. - -{{int:Lastmodifiedby}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lineno&action=edit lineno]
    -[[MediaWiki_talk:Lineno|Talk]] -
    -Line $1: - -{{int:Lineno}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Link_sample&action=edit link_sample]
    -[[MediaWiki_talk:Link_sample|Talk]] -
    -Link title - -{{int:Link_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Link_tip&action=edit link_tip]
    -[[MediaWiki_talk:Link_tip|Talk]] -
    -Internal link - -{{int:Link_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linklistsub&action=edit linklistsub]
    -[[MediaWiki_talk:Linklistsub|Talk]] -
    -(List of links) - -{{int:Linklistsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linkshere&action=edit linkshere]
    -[[MediaWiki_talk:Linkshere|Talk]] -
    -The following pages link to here: - -{{int:Linkshere}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linkstoimage&action=edit linkstoimage]
    -[[MediaWiki_talk:Linkstoimage|Talk]] -
    -The following pages link to this image: - -{{int:Linkstoimage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Linktrail&action=edit linktrail]
    -[[MediaWiki_talk:Linktrail|Talk]] -
    -/^([a-z]+)(.*)$/sD - -{{int:Linktrail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Listform&action=edit listform]
    -[[MediaWiki_talk:Listform|Talk]] -
    -list - -{{int:Listform}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Listusers&action=edit listusers]
    -[[MediaWiki_talk:Listusers|Talk]] -
    -User list - -{{int:Listusers}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loadhist&action=edit loadhist]
    -[[MediaWiki_talk:Loadhist|Talk]] -
    -Loading page history - -{{int:Loadhist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loadingrev&action=edit loadingrev]
    -[[MediaWiki_talk:Loadingrev|Talk]] -
    -loading revision for diff - -{{int:Loadingrev}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Localtime&action=edit localtime]
    -[[MediaWiki_talk:Localtime|Talk]] -
    -Local time display - -{{int:Localtime}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockbtn&action=edit lockbtn]
    -[[MediaWiki_talk:Lockbtn|Talk]] -
    -Lock database - -{{int:Lockbtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockconfirm&action=edit lockconfirm]
    -[[MediaWiki_talk:Lockconfirm|Talk]] -
    -Yes, I really want to lock the database. - -{{int:Lockconfirm}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdb&action=edit lockdb]
    -[[MediaWiki_talk:Lockdb|Talk]] -
    -Lock database - -{{int:Lockdb}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbsuccesssub&action=edit lockdbsuccesssub]
    -[[MediaWiki_talk:Lockdbsuccesssub|Talk]] -
    -Database lock succeeded - -{{int:Lockdbsuccesssub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbsuccesstext&action=edit lockdbsuccesstext]
    -[[MediaWiki_talk:Lockdbsuccesstext|Talk]] -
    -The database has been locked. -<br />Remember to remove the lock after your maintenance is complete. - -{{int:Lockdbsuccesstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lockdbtext&action=edit lockdbtext]
    -[[MediaWiki_talk:Lockdbtext|Talk]] -
    -Locking the database will suspend the ability of all -users to edit pages, change their preferences, edit their watchlists, and -other things requiring changes in the database. -Please confirm that this is what you intend to do, and that you will -unlock the database when your maintenance is done. - -{{int:Lockdbtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Locknoconfirm&action=edit locknoconfirm]
    -[[MediaWiki_talk:Locknoconfirm|Talk]] -
    -You did not check the confirmation box. - -{{int:Locknoconfirm}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Login&action=edit login]
    -[[MediaWiki_talk:Login|Talk]] -
    -Log in - -{{int:Login}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginend&action=edit loginend]
    -[[MediaWiki_talk:Loginend|Talk]] -
    -&nbsp; - -{{int:Loginend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginerror&action=edit loginerror]
    -[[MediaWiki_talk:Loginerror|Talk]] -
    -Login error - -{{int:Loginerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginpagetitle&action=edit loginpagetitle]
    -[[MediaWiki_talk:Loginpagetitle|Talk]] -
    -User login - -{{int:Loginpagetitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginproblem&action=edit loginproblem]
    -[[MediaWiki_talk:Loginproblem|Talk]] -
    -<b>There has been a problem with your login.</b><br />Try again! - -{{int:Loginproblem}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginprompt&action=edit loginprompt]
    -[[MediaWiki_talk:Loginprompt|Talk]] -
    -You must have cookies enabled to log in to Wiktionary. - -{{int:Loginprompt}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginreqtext&action=edit loginreqtext]
    -[[MediaWiki_talk:Loginreqtext|Talk]] -
    -You must [[special:Userlogin|login]] to view other pages. - -{{int:Loginreqtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginreqtitle&action=edit loginreqtitle]
    -[[MediaWiki_talk:Loginreqtitle|Talk]] -
    -Login Required - -{{int:Loginreqtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginsuccess&action=edit loginsuccess]
    -[[MediaWiki_talk:Loginsuccess|Talk]] -
    -You are now logged in to Wiktionary as "$1". - -{{int:Loginsuccess}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginsuccesstitle&action=edit loginsuccesstitle]
    -[[MediaWiki_talk:Loginsuccesstitle|Talk]] -
    -Login successful - -{{int:Loginsuccesstitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logout&action=edit logout]
    -[[MediaWiki_talk:Logout|Talk]] -
    -Log out - -{{int:Logout}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logouttext&action=edit logouttext]
    -[[MediaWiki_talk:Logouttext|Talk]] -
    -You are now logged out. -You can continue to use Wiktionary anonymously, or you can log in -again as the same or as a different user. Note that some pages may -continue to be displayed as if you were still logged in, until you clear -your browser cache - - -{{int:Logouttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Logouttitle&action=edit logouttitle]
    -[[MediaWiki_talk:Logouttitle|Talk]] -
    -User logout - -{{int:Logouttitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Lonelypages&action=edit lonelypages]
    -[[MediaWiki_talk:Lonelypages|Talk]] -
    -Orphaned pages - -{{int:Lonelypages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Longpages&action=edit longpages]
    -[[MediaWiki_talk:Longpages|Talk]] -
    -Long pages - -{{int:Longpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Longpagewarning&action=edit longpagewarning]
    -[[MediaWiki_talk:Longpagewarning|Talk]] -
    -WARNING: This page is $1 kilobytes long; some -browsers may have problems editing pages approaching or longer than 32kb. -Please consider breaking the page into smaller sections. - -{{int:Longpagewarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailerror&action=edit mailerror]
    -[[MediaWiki_talk:Mailerror|Talk]] -
    -Error sending mail: $1 - -{{int:Mailerror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailmypassword&action=edit mailmypassword]
    -[[MediaWiki_talk:Mailmypassword|Talk]] -
    -Mail me a new password - -{{int:Mailmypassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailnologin&action=edit mailnologin]
    -[[MediaWiki_talk:Mailnologin|Talk]] -
    -No send address - -{{int:Mailnologin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mailnologintext&action=edit mailnologintext]
    -[[MediaWiki_talk:Mailnologintext|Talk]] -
    -You must be <a href="{{localurl:Special:Userlogin">logged in</a> -and have a valid e-mail address in your <a href="/wiki/Special:Preferences">preferences</a> -to send e-mail to other users. - -{{int:Mailnologintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpage&action=edit mainpage]
    -[[MediaWiki_talk:Mainpage|Talk]] -
    -Main Page - -{{int:Mainpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpagedocfooter&action=edit mainpagedocfooter]
    -[[MediaWiki_talk:Mainpagedocfooter|Talk]] -
    -Please see [http://meta.wikipedia.org/wiki/MediaWiki_i18n documentation on customizing the interface] -and the [http://meta.wikipedia.org/wiki/MediaWiki_User%27s_Guide User's Guide] for usage and configuration help. - -{{int:Mainpagedocfooter}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mainpagetext&action=edit mainpagetext]
    -[[MediaWiki_talk:Mainpagetext|Talk]] -
    -Wiki software successfully installed. - -{{int:Mainpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintenance&action=edit maintenance]
    -[[MediaWiki_talk:Maintenance|Talk]] -
    -Maintenance page - -{{int:Maintenance}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintenancebacklink&action=edit maintenancebacklink]
    -[[MediaWiki_talk:Maintenancebacklink|Talk]] -
    -Back to Maintenance Page - -{{int:Maintenancebacklink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Maintnancepagetext&action=edit maintnancepagetext]
    -[[MediaWiki_talk:Maintnancepagetext|Talk]] -
    -This page includes several handy tools for everyday maintenance. Some of these functions tend to stress the database, so please do not hit reload after every item you fixed ;-) - -{{int:Maintnancepagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysop&action=edit makesysop]
    -[[MediaWiki_talk:Makesysop|Talk]] -
    -Make a user into a sysop - -{{int:Makesysop}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopfail&action=edit makesysopfail]
    -[[MediaWiki_talk:Makesysopfail|Talk]] -
    -<b>User "$1" could not be made into a sysop. (Did you enter the name correctly?)</b> - -{{int:Makesysopfail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopname&action=edit makesysopname]
    -[[MediaWiki_talk:Makesysopname|Talk]] -
    -Name of the user: - -{{int:Makesysopname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopok&action=edit makesysopok]
    -[[MediaWiki_talk:Makesysopok|Talk]] -
    -<b>User "$1" is now a sysop</b> - -{{int:Makesysopok}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysopsubmit&action=edit makesysopsubmit]
    -[[MediaWiki_talk:Makesysopsubmit|Talk]] -
    -Make this user into a sysop - -{{int:Makesysopsubmit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysoptext&action=edit makesysoptext]
    -[[MediaWiki_talk:Makesysoptext|Talk]] -
    -This form is used by bureaucrats to turn ordinary users into administrators. -Type the name of the user in the box and press the button to make the user an administrator - -{{int:Makesysoptext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Makesysoptitle&action=edit makesysoptitle]
    -[[MediaWiki_talk:Makesysoptitle|Talk]] -
    -Make a user into a sysop - -{{int:Makesysoptitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Matchtotals&action=edit matchtotals]
    -[[MediaWiki_talk:Matchtotals|Talk]] -
    -The query "$1" matched $2 page titles -and the text of $3 pages. - -{{int:Matchtotals}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math&action=edit math]
    -[[MediaWiki_talk:Math|Talk]] -
    -Rendering math - -{{int:Math}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_bad_output&action=edit math_bad_output]
    -[[MediaWiki_talk:Math_bad_output|Talk]] -
    -Can't write to or create math output directory - -{{int:Math_bad_output}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_bad_tmpdir&action=edit math_bad_tmpdir]
    -[[MediaWiki_talk:Math_bad_tmpdir|Talk]] -
    -Can't write to or create math temp directory - -{{int:Math_bad_tmpdir}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_failure&action=edit math_failure]
    -[[MediaWiki_talk:Math_failure|Talk]] -
    -Failed to parse - -{{int:Math_failure}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_image_error&action=edit math_image_error]
    -[[MediaWiki_talk:Math_image_error|Talk]] -
    -PNG conversion failed; check for correct installation of latex, dvips, gs, and convert - -{{int:Math_image_error}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_lexing_error&action=edit math_lexing_error]
    -[[MediaWiki_talk:Math_lexing_error|Talk]] -
    -lexing error - -{{int:Math_lexing_error}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_notexvc&action=edit math_notexvc]
    -[[MediaWiki_talk:Math_notexvc|Talk]] -
    -Missing texvc executable; please see math/README to configure. - -{{int:Math_notexvc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_sample&action=edit math_sample]
    -[[MediaWiki_talk:Math_sample|Talk]] -
    -Insert formula here - -{{int:Math_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_syntax_error&action=edit math_syntax_error]
    -[[MediaWiki_talk:Math_syntax_error|Talk]] -
    -syntax error - -{{int:Math_syntax_error}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_tip&action=edit math_tip]
    -[[MediaWiki_talk:Math_tip|Talk]] -
    -Mathematical formula (LaTeX) - -{{int:Math_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_unknown_error&action=edit math_unknown_error]
    -[[MediaWiki_talk:Math_unknown_error|Talk]] -
    -unknown error - -{{int:Math_unknown_error}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Math_unknown_function&action=edit math_unknown_function]
    -[[MediaWiki_talk:Math_unknown_function|Talk]] -
    -unknown function - -{{int:Math_unknown_function}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Media_sample&action=edit media_sample]
    -[[MediaWiki_talk:Media_sample|Talk]] -
    -Example.mp3 - -{{int:Media_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Media_tip&action=edit media_tip]
    -[[MediaWiki_talk:Media_tip|Talk]] -
    -Media file link - -{{int:Media_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minlength&action=edit minlength]
    -[[MediaWiki_talk:Minlength|Talk]] -
    -Image names must be at least three letters. - -{{int:Minlength}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minoredit&action=edit minoredit]
    -[[MediaWiki_talk:Minoredit|Talk]] -
    -This is a minor edit - -{{int:Minoredit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Minoreditletter&action=edit minoreditletter]
    -[[MediaWiki_talk:Minoreditletter|Talk]] -
    -M - -{{int:Minoreditletter}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelings&action=edit mispeelings]
    -[[MediaWiki_talk:Mispeelings|Talk]] -
    -Pages with misspellings - -{{int:Mispeelings}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelingspage&action=edit mispeelingspage]
    -[[MediaWiki_talk:Mispeelingspage|Talk]] -
    -List of common misspellings - -{{int:Mispeelingspage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mispeelingstext&action=edit mispeelingstext]
    -[[MediaWiki_talk:Mispeelingstext|Talk]] -
    -The following pages contain a common misspelling, which are listed on $1. The correct spelling might be given (like this). - -{{int:Mispeelingstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missingarticle&action=edit missingarticle]
    -[[MediaWiki_talk:Missingarticle|Talk]] -
    -The database did not find the text of a page -that it should have found, named "$1". - -<p>This is usually caused by following an outdated diff or history link to a -page that has been deleted. - -<p>If this is not the case, you may have found a bug in the software. -Please report this to an administrator, making note of the URL. - -{{int:Missingarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missingimage&action=edit missingimage]
    -[[MediaWiki_talk:Missingimage|Talk]] -
    -<b>Missing image</b><br /><i>$1</i> - - -{{int:Missingimage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinks&action=edit missinglanguagelinks]
    -[[MediaWiki_talk:Missinglanguagelinks|Talk]] -
    -Missing Language Links - -{{int:Missinglanguagelinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinksbutton&action=edit missinglanguagelinksbutton]
    -[[MediaWiki_talk:Missinglanguagelinksbutton|Talk]] -
    -Find missing language links for - -{{int:Missinglanguagelinksbutton}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Missinglanguagelinkstext&action=edit missinglanguagelinkstext]
    -[[MediaWiki_talk:Missinglanguagelinkstext|Talk]] -
    -These pages do <i>not</i> link to their counterpart in $1. Redirects and subpages are <i>not</i> shown. - -{{int:Missinglanguagelinkstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Moredotdotdot&action=edit moredotdotdot]
    -[[MediaWiki_talk:Moredotdotdot|Talk]] -
    -More... - -{{int:Moredotdotdot}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Move&action=edit move]
    -[[MediaWiki_talk:Move|Talk]] -
    -Move - -{{int:Move}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movearticle&action=edit movearticle]
    -[[MediaWiki_talk:Movearticle|Talk]] -
    -Move page - -{{int:Movearticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movedto&action=edit movedto]
    -[[MediaWiki_talk:Movedto|Talk]] -
    -moved to - -{{int:Movedto}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movenologin&action=edit movenologin]
    -[[MediaWiki_talk:Movenologin|Talk]] -
    -Not logged in - -{{int:Movenologin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movenologintext&action=edit movenologintext]
    -[[MediaWiki_talk:Movenologintext|Talk]] -
    -You must be a registered user and <a href="/wiki/Special:Userlogin">logged in</a> -to move a page. - -{{int:Movenologintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepage&action=edit movepage]
    -[[MediaWiki_talk:Movepage|Talk]] -
    -Move page - -{{int:Movepage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagebtn&action=edit movepagebtn]
    -[[MediaWiki_talk:Movepagebtn|Talk]] -
    -Move page - -{{int:Movepagebtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagetalktext&action=edit movepagetalktext]
    -[[MediaWiki_talk:Movepagetalktext|Talk]] -
    -The associated talk page, if any, will be automatically moved along with it '''unless:''' -*You are moving the page across namespaces, -*A non-empty talk page already exists under the new name, or -*You uncheck the box below. - -In those cases, you will have to move or merge the page manually if desired. - -{{int:Movepagetalktext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movepagetext&action=edit movepagetext]
    -[[MediaWiki_talk:Movepagetext|Talk]] -
    -Using the form below will rename a page, moving all -of its history to the new name. -The old title will become a redirect page to the new title. -Links to the old page title will not be changed; be sure to -[[Special:Maintenance|check]] for double or broken redirects. -You are responsible for making sure that links continue to -point where they are supposed to go. - -Note that the page will '''not''' be moved if there is already -a page at the new title, unless it is empty or a redirect and has no -past edit history. This means that you can rename a page back to where -it was just renamed from if you make a mistake, and you cannot overwrite -an existing page. - -<b>WARNING!</b> -This can be a drastic and unexpected change for a popular page; -please be sure you understand the consequences of this before -proceeding. - -{{int:Movepagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movetalk&action=edit movetalk]
    -[[MediaWiki_talk:Movetalk|Talk]] -
    -Move "talk" page as well, if applicable. - -{{int:Movetalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Movethispage&action=edit movethispage]
    -[[MediaWiki_talk:Movethispage|Talk]] -
    -Move this page - -{{int:Movethispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mycontris&action=edit mycontris]
    -[[MediaWiki_talk:Mycontris|Talk]] -
    -My contributions - -{{int:Mycontris}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mypage&action=edit mypage]
    -[[MediaWiki_talk:Mypage|Talk]] -
    -My page - -{{int:Mypage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Mytalk&action=edit mytalk]
    -[[MediaWiki_talk:Mytalk|Talk]] -
    -My talk - -{{int:Mytalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Navigation&action=edit navigation]
    -[[MediaWiki_talk:Navigation|Talk]] -
    -Navigation - -{{int:Navigation}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nbytes&action=edit nbytes]
    -[[MediaWiki_talk:Nbytes|Talk]] -
    -$1 bytes - -{{int:Nbytes}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nchanges&action=edit nchanges]
    -[[MediaWiki_talk:Nchanges|Talk]] -
    -$1 changes - -{{int:Nchanges}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newarticle&action=edit newarticle]
    -[[MediaWiki_talk:Newarticle|Talk]] -
    -(New) - -{{int:Newarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newarticletext&action=edit newarticletext]
    -[[MediaWiki_talk:Newarticletext|Talk]] -
    -You've followed a link to a page that doesn't exist yet. -To create the page, start typing in the box below -(see the [[Wiktionary:Help|help page]] for more info). -If you are here by mistake, just click your browser's '''back''' button. - -{{int:Newarticletext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newmessages&action=edit newmessages]
    -[[MediaWiki_talk:Newmessages|Talk]] -
    -You have $1. - -{{int:Newmessages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newmessageslink&action=edit newmessageslink]
    -[[MediaWiki_talk:Newmessageslink|Talk]] -
    -new messages - -{{int:Newmessageslink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpage&action=edit newpage]
    -[[MediaWiki_talk:Newpage|Talk]] -
    -New page - -{{int:Newpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpageletter&action=edit newpageletter]
    -[[MediaWiki_talk:Newpageletter|Talk]] -
    -N - -{{int:Newpageletter}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpages&action=edit newpages]
    -[[MediaWiki_talk:Newpages|Talk]] -
    -New pages - -{{int:Newpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newpassword&action=edit newpassword]
    -[[MediaWiki_talk:Newpassword|Talk]] -
    -New password - -{{int:Newpassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newtitle&action=edit newtitle]
    -[[MediaWiki_talk:Newtitle|Talk]] -
    -To new title - -{{int:Newtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Newusersonly&action=edit newusersonly]
    -[[MediaWiki_talk:Newusersonly|Talk]] -
    - (new users only) - -{{int:Newusersonly}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Next&action=edit next]
    -[[MediaWiki_talk:Next|Talk]] -
    -next - -{{int:Next}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nextn&action=edit nextn]
    -[[MediaWiki_talk:Nextn|Talk]] -
    -next $1 - -{{int:Nextn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nlinks&action=edit nlinks]
    -[[MediaWiki_talk:Nlinks|Talk]] -
    -$1 links - -{{int:Nlinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noaffirmation&action=edit noaffirmation]
    -[[MediaWiki_talk:Noaffirmation|Talk]] -
    -You must affirm that your upload does not violate -any copyrights. - -{{int:Noaffirmation}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noarticletext&action=edit noarticletext]
    -[[MediaWiki_talk:Noarticletext|Talk]] -
    -(There is currently no text in this page) - -{{int:Noarticletext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noblockreason&action=edit noblockreason]
    -[[MediaWiki_talk:Noblockreason|Talk]] -
    -You must supply a reason for the block. - -{{int:Noblockreason}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noconnect&action=edit noconnect]
    -[[MediaWiki_talk:Noconnect|Talk]] -
    -Sorry! The wiki is experiencing some technical difficulties, and cannot contact the database server. - -{{int:Noconnect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocontribs&action=edit nocontribs]
    -[[MediaWiki_talk:Nocontribs|Talk]] -
    -No changes were found matching these criteria. - -{{int:Nocontribs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocookieslogin&action=edit nocookieslogin]
    -[[MediaWiki_talk:Nocookieslogin|Talk]] -
    -Wiktionary uses cookies to log in users. You have cookies disabled. Please enable them and try again. - -{{int:Nocookieslogin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocookiesnew&action=edit nocookiesnew]
    -[[MediaWiki_talk:Nocookiesnew|Talk]] -
    -The user account was created, but you are not logged in. Wiktionary uses cookies to log in users. You have cookies disabled. Please enable them, then log in with your new username and password. - -{{int:Nocookiesnew}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nocreativecommons&action=edit nocreativecommons]
    -[[MediaWiki_talk:Nocreativecommons|Talk]] -
    -Creative Commons RDF metadata disabled for this server. - -{{int:Nocreativecommons}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nodb&action=edit nodb]
    -[[MediaWiki_talk:Nodb|Talk]] -
    -Could not select database $1 - -{{int:Nodb}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nodublincore&action=edit nodublincore]
    -[[MediaWiki_talk:Nodublincore|Talk]] -
    -Dublin Core RDF metadata disabled for this server. - -{{int:Nodublincore}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemail&action=edit noemail]
    -[[MediaWiki_talk:Noemail|Talk]] -
    -There is no e-mail address recorded for user "$1". - -{{int:Noemail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemailtext&action=edit noemailtext]
    -[[MediaWiki_talk:Noemailtext|Talk]] -
    -This user has not specified a valid e-mail address, -or has chosen not to receive e-mail from other users. - -{{int:Noemailtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noemailtitle&action=edit noemailtitle]
    -[[MediaWiki_talk:Noemailtitle|Talk]] -
    -No e-mail address - -{{int:Noemailtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nogomatch&action=edit nogomatch]
    -[[MediaWiki_talk:Nogomatch|Talk]] -
    -No page with this exact title exists, trying full text search. - -{{int:Nogomatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nohistory&action=edit nohistory]
    -[[MediaWiki_talk:Nohistory|Talk]] -
    -There is no edit history for this page. - -{{int:Nohistory}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nolinkshere&action=edit nolinkshere]
    -[[MediaWiki_talk:Nolinkshere|Talk]] -
    -No pages link to here. - -{{int:Nolinkshere}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nolinkstoimage&action=edit nolinkstoimage]
    -[[MediaWiki_talk:Nolinkstoimage|Talk]] -
    -There are no pages that link to this image. - -{{int:Nolinkstoimage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Noname&action=edit noname]
    -[[MediaWiki_talk:Noname|Talk]] -
    -You have not specified a valid user name. - -{{int:Noname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nonefound&action=edit nonefound]
    -[[MediaWiki_talk:Nonefound|Talk]] -
    -<strong>Note</strong>: unsuccessful searches are -often caused by searching for common words like "have" and "from", -which are not indexed, or by specifying more than one search term (only pages -containing all of the search terms will appear in the result). - -{{int:Nonefound}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nospecialpagetext&action=edit nospecialpagetext]
    -[[MediaWiki_talk:Nospecialpagetext|Talk]] -
    -You have requested a special page that is not -recognized by the wiki. - -{{int:Nospecialpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchaction&action=edit nosuchaction]
    -[[MediaWiki_talk:Nosuchaction|Talk]] -
    -No such action - -{{int:Nosuchaction}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchactiontext&action=edit nosuchactiontext]
    -[[MediaWiki_talk:Nosuchactiontext|Talk]] -
    -The action specified by the URL is not -recognized by the wiki - -{{int:Nosuchactiontext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchspecialpage&action=edit nosuchspecialpage]
    -[[MediaWiki_talk:Nosuchspecialpage|Talk]] -
    -No such special page - -{{int:Nosuchspecialpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nosuchuser&action=edit nosuchuser]
    -[[MediaWiki_talk:Nosuchuser|Talk]] -
    -There is no user by the name "$1". -Check your spelling, or use the form below to create a new user account. - -{{int:Nosuchuser}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notacceptable&action=edit notacceptable]
    -[[MediaWiki_talk:Notacceptable|Talk]] -
    -The wiki server can't provide data in a format your client can read. - -{{int:Notacceptable}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notanarticle&action=edit notanarticle]
    -[[MediaWiki_talk:Notanarticle|Talk]] -
    -Not a content page - -{{int:Notanarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notargettext&action=edit notargettext]
    -[[MediaWiki_talk:Notargettext|Talk]] -
    -You have not specified a target page or user -to perform this function on. - -{{int:Notargettext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notargettitle&action=edit notargettitle]
    -[[MediaWiki_talk:Notargettitle|Talk]] -
    -No target - -{{int:Notargettitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Note&action=edit note]
    -[[MediaWiki_talk:Note|Talk]] -
    -<strong>Note:</strong> - -{{int:Note}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notextmatches&action=edit notextmatches]
    -[[MediaWiki_talk:Notextmatches|Talk]] -
    -No page text matches - -{{int:Notextmatches}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notitlematches&action=edit notitlematches]
    -[[MediaWiki_talk:Notitlematches|Talk]] -
    -No page title matches - -{{int:Notitlematches}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Notloggedin&action=edit notloggedin]
    -[[MediaWiki_talk:Notloggedin|Talk]] -
    -Not logged in - -{{int:Notloggedin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowatchlist&action=edit nowatchlist]
    -[[MediaWiki_talk:Nowatchlist|Talk]] -
    -You have no items on your watchlist. - -{{int:Nowatchlist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowiki_sample&action=edit nowiki_sample]
    -[[MediaWiki_talk:Nowiki_sample|Talk]] -
    -Insert non-formatted text here - -{{int:Nowiki_sample}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nowiki_tip&action=edit nowiki_tip]
    -[[MediaWiki_talk:Nowiki_tip|Talk]] -
    -Ignore wiki formatting - -{{int:Nowiki_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-category&action=edit nstab-category]
    -[[MediaWiki_talk:Nstab-category|Talk]] -
    -Category - -{{int:Nstab-category}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-help&action=edit nstab-help]
    -[[MediaWiki_talk:Nstab-help|Talk]] -
    -Help - -{{int:Nstab-help}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-image&action=edit nstab-image]
    -[[MediaWiki_talk:Nstab-image|Talk]] -
    -Image - -{{int:Nstab-image}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-main&action=edit nstab-main]
    -[[MediaWiki_talk:Nstab-main|Talk]] -
    -Article - -{{int:Nstab-main}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-media&action=edit nstab-media]
    -[[MediaWiki_talk:Nstab-media|Talk]] -
    -Media - -{{int:Nstab-media}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-mediawiki&action=edit nstab-mediawiki]
    -[[MediaWiki_talk:Nstab-mediawiki|Talk]] -
    -Message - -{{int:Nstab-mediawiki}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-special&action=edit nstab-special]
    -[[MediaWiki_talk:Nstab-special|Talk]] -
    -Special - -{{int:Nstab-special}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-template&action=edit nstab-template]
    -[[MediaWiki_talk:Nstab-template|Talk]] -
    -Template - -{{int:Nstab-template}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-user&action=edit nstab-user]
    -[[MediaWiki_talk:Nstab-user|Talk]] -
    -User page - -{{int:Nstab-user}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nstab-wp&action=edit nstab-wp]
    -[[MediaWiki_talk:Nstab-wp|Talk]] -
    -About - -{{int:Nstab-wp}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Nviews&action=edit nviews]
    -[[MediaWiki_talk:Nviews|Talk]] -
    -$1 views - -{{int:Nviews}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ok&action=edit ok]
    -[[MediaWiki_talk:Ok|Talk]] -
    -OK - -{{int:Ok}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Oldpassword&action=edit oldpassword]
    -[[MediaWiki_talk:Oldpassword|Talk]] -
    -Old password - -{{int:Oldpassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Orig&action=edit orig]
    -[[MediaWiki_talk:Orig|Talk]] -
    -orig - -{{int:Orig}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Orphans&action=edit orphans]
    -[[MediaWiki_talk:Orphans|Talk]] -
    -Orphaned pages - -{{int:Orphans}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Othercontribs&action=edit othercontribs]
    -[[MediaWiki_talk:Othercontribs|Talk]] -
    -Based on work by $1. - -{{int:Othercontribs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Otherlanguages&action=edit otherlanguages]
    -[[MediaWiki_talk:Otherlanguages|Talk]] -
    -Other languages - -{{int:Otherlanguages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagemovedsub&action=edit pagemovedsub]
    -[[MediaWiki_talk:Pagemovedsub|Talk]] -
    -Move succeeded - -{{int:Pagemovedsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagemovedtext&action=edit pagemovedtext]
    -[[MediaWiki_talk:Pagemovedtext|Talk]] -
    -Page "[[$1]]" moved to "[[$2]]". - -{{int:Pagemovedtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Pagetitle&action=edit pagetitle]
    -[[MediaWiki_talk:Pagetitle|Talk]] -
    -$1 - Wiktionary - -{{int:Pagetitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordremindertext&action=edit passwordremindertext]
    -[[MediaWiki_talk:Passwordremindertext|Talk]] -
    -Someone (probably you, from IP address $1) -requested that we send you a new Wiktionary login password. -The password for user "$2" is now "$3". -You should log in and change your password now. - -{{int:Passwordremindertext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordremindertitle&action=edit passwordremindertitle]
    -[[MediaWiki_talk:Passwordremindertitle|Talk]] -
    -Password reminder from Wiktionary - -{{int:Passwordremindertitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Passwordsent&action=edit passwordsent]
    -[[MediaWiki_talk:Passwordsent|Talk]] -
    -A new password has been sent to the e-mail address -registered for "$1". -Please log in again after you receive it. - -{{int:Passwordsent}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfcached&action=edit perfcached]
    -[[MediaWiki_talk:Perfcached|Talk]] -
    -The following data is cached and may not be completely up to date: - -{{int:Perfcached}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfdisabled&action=edit perfdisabled]
    -[[MediaWiki_talk:Perfdisabled|Talk]] -
    -Sorry! This feature has been temporarily disabled -because it slows the database down to the point that no one can use -the wiki. - -{{int:Perfdisabled}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Perfdisabledsub&action=edit perfdisabledsub]
    -[[MediaWiki_talk:Perfdisabledsub|Talk]] -
    -Here's a saved copy from $1: - -{{int:Perfdisabledsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Personaltools&action=edit personaltools]
    -[[MediaWiki_talk:Personaltools|Talk]] -
    -Personal tools - -{{int:Personaltools}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Popularpages&action=edit popularpages]
    -[[MediaWiki_talk:Popularpages|Talk]] -
    -Popular pages - -{{int:Popularpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Portal&action=edit portal]
    -[[MediaWiki_talk:Portal|Talk]] -
    -Community portal - -{{int:Portal}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Portal-url&action=edit portal-url]
    -[[MediaWiki_talk:Portal-url|Talk]] -
    -Wiktionary:Community Portal - -{{int:Portal-url}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Postcomment&action=edit postcomment]
    -[[MediaWiki_talk:Postcomment|Talk]] -
    -Post a comment - -{{int:Postcomment}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Poweredby&action=edit poweredby]
    -[[MediaWiki_talk:Poweredby|Talk]] -
    -Wiktionary is powered by [http://www.mediawiki.org/ MediaWiki], an open source wiki engine. - -{{int:Poweredby}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Powersearch&action=edit powersearch]
    -[[MediaWiki_talk:Powersearch|Talk]] -
    -Search - -{{int:Powersearch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Powersearchtext&action=edit powersearchtext]
    -[[MediaWiki_talk:Powersearchtext|Talk]] -
    - -Search in namespaces :<br /> -$1<br /> -$2 List redirects &nbsp; Search for $3 $9 - -{{int:Powersearchtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Preferences&action=edit preferences]
    -[[MediaWiki_talk:Preferences|Talk]] -
    -Preferences - -{{int:Preferences}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-help-userdata&action=edit prefs-help-userdata]
    -[[MediaWiki_talk:Prefs-help-userdata|Talk]] -
    -* <strong>Real name</strong> (optional): if you choose to provide it this will be used for giving you attribution for your work.<br/> -* <strong>Email</strong> (optional): Enables people to contact you through the website without you having to reveal your -email address to them, and it can be used to send you a new password if you forget it. - -{{int:Prefs-help-userdata}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-misc&action=edit prefs-misc]
    -[[MediaWiki_talk:Prefs-misc|Talk]] -
    -Misc settings - -{{int:Prefs-misc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-personal&action=edit prefs-personal]
    -[[MediaWiki_talk:Prefs-personal|Talk]] -
    -User data - -{{int:Prefs-personal}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefs-rc&action=edit prefs-rc]
    -[[MediaWiki_talk:Prefs-rc|Talk]] -
    -Recent changes and stub display - -{{int:Prefs-rc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefslogintext&action=edit prefslogintext]
    -[[MediaWiki_talk:Prefslogintext|Talk]] -
    -You are logged in as "$1". -Your internal ID number is $2. - -See [[Wiktionary:User preferences help]] for help deciphering the options. - -{{int:Prefslogintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsnologin&action=edit prefsnologin]
    -[[MediaWiki_talk:Prefsnologin|Talk]] -
    -Not logged in - -{{int:Prefsnologin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsnologintext&action=edit prefsnologintext]
    -[[MediaWiki_talk:Prefsnologintext|Talk]] -
    -You must be <a href="/wiki/Special:Userlogin">logged in</a> -to set user preferences. - -{{int:Prefsnologintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prefsreset&action=edit prefsreset]
    -[[MediaWiki_talk:Prefsreset|Talk]] -
    -Preferences have been reset from storage. - -{{int:Prefsreset}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Preview&action=edit preview]
    -[[MediaWiki_talk:Preview|Talk]] -
    -Preview - -{{int:Preview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Previewconflict&action=edit previewconflict]
    -[[MediaWiki_talk:Previewconflict|Talk]] -
    -This preview reflects the text in the upper -text editing area as it will appear if you choose to save. - -{{int:Previewconflict}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Previewnote&action=edit previewnote]
    -[[MediaWiki_talk:Previewnote|Talk]] -
    -Remember that this is only a preview, and has not yet been saved! - -{{int:Previewnote}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Prevn&action=edit prevn]
    -[[MediaWiki_talk:Prevn|Talk]] -
    -previous $1 - -{{int:Prevn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Printableversion&action=edit printableversion]
    -[[MediaWiki_talk:Printableversion|Talk]] -
    -Printable version - -{{int:Printableversion}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Printsubtitle&action=edit printsubtitle]
    -[[MediaWiki_talk:Printsubtitle|Talk]] -
    -(From http://tl.wiktionary.org) - -{{int:Printsubtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protect&action=edit protect]
    -[[MediaWiki_talk:Protect|Talk]] -
    -Protect - -{{int:Protect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectcomment&action=edit protectcomment]
    -[[MediaWiki_talk:Protectcomment|Talk]] -
    -Reason for protecting - -{{int:Protectcomment}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedarticle&action=edit protectedarticle]
    -[[MediaWiki_talk:Protectedarticle|Talk]] -
    -protected [[$1]] - -{{int:Protectedarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedpage&action=edit protectedpage]
    -[[MediaWiki_talk:Protectedpage|Talk]] -
    -Protected page - -{{int:Protectedpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedpagewarning&action=edit protectedpagewarning]
    -[[MediaWiki_talk:Protectedpagewarning|Talk]] -
    -WARNING: This page has been locked so that only -users with sysop privileges can edit it. Be sure you are following the -<a href='/w/wiki.phtml/Wiktionary:Protected_page_guidelines'>protected page -guidelines</a>. - -{{int:Protectedpagewarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectedtext&action=edit protectedtext]
    -[[MediaWiki_talk:Protectedtext|Talk]] -
    -This page has been locked to prevent editing; there are -a number of reasons why this may be so, please see -[[Wiktionary:Protected page]]. - -You can view and copy the source of this page: - -{{int:Protectedtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectlogpage&action=edit protectlogpage]
    -[[MediaWiki_talk:Protectlogpage|Talk]] -
    -Protection_log - -{{int:Protectlogpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectlogtext&action=edit protectlogtext]
    -[[MediaWiki_talk:Protectlogtext|Talk]] -
    -Below is a list of page locks/unlocks. -See [[Wiktionary:Protected page]] for more information. - -{{int:Protectlogtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectpage&action=edit protectpage]
    -[[MediaWiki_talk:Protectpage|Talk]] -
    -Protect page - -{{int:Protectpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectreason&action=edit protectreason]
    -[[MediaWiki_talk:Protectreason|Talk]] -
    -(give a reason) - -{{int:Protectreason}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectsub&action=edit protectsub]
    -[[MediaWiki_talk:Protectsub|Talk]] -
    -(Protecting "$1") - -{{int:Protectsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Protectthispage&action=edit protectthispage]
    -[[MediaWiki_talk:Protectthispage|Talk]] -
    -Protect this page - -{{int:Protectthispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblocker&action=edit proxyblocker]
    -[[MediaWiki_talk:Proxyblocker|Talk]] -
    -Proxy blocker - -{{int:Proxyblocker}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblockreason&action=edit proxyblockreason]
    -[[MediaWiki_talk:Proxyblockreason|Talk]] -
    -Your IP address has been blocked because it is an open proxy. Please contact your Internet service provider or tech support and inform them of this serious security problem. - -{{int:Proxyblockreason}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Proxyblocksuccess&action=edit proxyblocksuccess]
    -[[MediaWiki_talk:Proxyblocksuccess|Talk]] -
    -Done. - - -{{int:Proxyblocksuccess}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbbrowse&action=edit qbbrowse]
    -[[MediaWiki_talk:Qbbrowse|Talk]] -
    -Browse - -{{int:Qbbrowse}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbedit&action=edit qbedit]
    -[[MediaWiki_talk:Qbedit|Talk]] -
    -Edit - -{{int:Qbedit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbfind&action=edit qbfind]
    -[[MediaWiki_talk:Qbfind|Talk]] -
    -Find - -{{int:Qbfind}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbmyoptions&action=edit qbmyoptions]
    -[[MediaWiki_talk:Qbmyoptions|Talk]] -
    -My pages - -{{int:Qbmyoptions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbpageinfo&action=edit qbpageinfo]
    -[[MediaWiki_talk:Qbpageinfo|Talk]] -
    -Context - -{{int:Qbpageinfo}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbpageoptions&action=edit qbpageoptions]
    -[[MediaWiki_talk:Qbpageoptions|Talk]] -
    -This page - -{{int:Qbpageoptions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbsettings&action=edit qbsettings]
    -[[MediaWiki_talk:Qbsettings|Talk]] -
    -Quickbar settings - -{{int:Qbsettings}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Qbspecialpages&action=edit qbspecialpages]
    -[[MediaWiki_talk:Qbspecialpages|Talk]] -
    -Special pages - -{{int:Qbspecialpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Querybtn&action=edit querybtn]
    -[[MediaWiki_talk:Querybtn|Talk]] -
    -Submit query - -{{int:Querybtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Querysuccessful&action=edit querysuccessful]
    -[[MediaWiki_talk:Querysuccessful|Talk]] -
    -Query successful - -{{int:Querysuccessful}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Randompage&action=edit randompage]
    -[[MediaWiki_talk:Randompage|Talk]] -
    -Random page - -{{int:Randompage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Range_block_disabled&action=edit range_block_disabled]
    -[[MediaWiki_talk:Range_block_disabled|Talk]] -
    -The sysop ability to create range blocks is disabled. - -{{int:Range_block_disabled}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rchide&action=edit rchide]
    -[[MediaWiki_talk:Rchide|Talk]] -
    -in $4 form; $1 minor edits; $2 secondary namespaces; $3 multiple edits. - -{{int:Rchide}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclinks&action=edit rclinks]
    -[[MediaWiki_talk:Rclinks|Talk]] -
    -Show last $1 changes in last $2 days<br />$3 - -{{int:Rclinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclistfrom&action=edit rclistfrom]
    -[[MediaWiki_talk:Rclistfrom|Talk]] -
    -Show new changes starting from $1 - -{{int:Rclistfrom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcliu&action=edit rcliu]
    -[[MediaWiki_talk:Rcliu|Talk]] -
    -; $1 edits from logged in users - -{{int:Rcliu}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcloaderr&action=edit rcloaderr]
    -[[MediaWiki_talk:Rcloaderr|Talk]] -
    -Loading recent changes - -{{int:Rcloaderr}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rclsub&action=edit rclsub]
    -[[MediaWiki_talk:Rclsub|Talk]] -
    -(to pages linked from "$1") - -{{int:Rclsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcnote&action=edit rcnote]
    -[[MediaWiki_talk:Rcnote|Talk]] -
    -Below are the last <strong>$1</strong> changes in last <strong>$2</strong> days. - -{{int:Rcnote}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rcnotefrom&action=edit rcnotefrom]
    -[[MediaWiki_talk:Rcnotefrom|Talk]] -
    -Below are the changes since <b>$2</b> (up to <b>$1</b> shown). - -{{int:Rcnotefrom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonly&action=edit readonly]
    -[[MediaWiki_talk:Readonly|Talk]] -
    -Database locked - -{{int:Readonly}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonlytext&action=edit readonlytext]
    -[[MediaWiki_talk:Readonlytext|Talk]] -
    -The database is currently locked to new -entries and other modifications, probably for routine database maintenance, -after which it will be back to normal. -The administrator who locked it offered this explanation: -<p>$1 - -{{int:Readonlytext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Readonlywarning&action=edit readonlywarning]
    -[[MediaWiki_talk:Readonlywarning|Talk]] -
    -WARNING: The database has been locked for maintenance, -so you will not be able to save your edits right now. You may wish to cut-n-paste -the text into a text file and save it for later. - -{{int:Readonlywarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchanges&action=edit recentchanges]
    -[[MediaWiki_talk:Recentchanges|Talk]] -
    -Recent changes - -{{int:Recentchanges}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangescount&action=edit recentchangescount]
    -[[MediaWiki_talk:Recentchangescount|Talk]] -
    -Number of titles in recent changes - -{{int:Recentchangescount}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangeslinked&action=edit recentchangeslinked]
    -[[MediaWiki_talk:Recentchangeslinked|Talk]] -
    -Related changes - -{{int:Recentchangeslinked}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Recentchangestext&action=edit recentchangestext]
    -[[MediaWiki_talk:Recentchangestext|Talk]] -
    -Track the most recent changes to the wiki on this page. - -{{int:Recentchangestext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Redirectedfrom&action=edit redirectedfrom]
    -[[MediaWiki_talk:Redirectedfrom|Talk]] -
    -(Redirected from $1) - -{{int:Redirectedfrom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Remembermypassword&action=edit remembermypassword]
    -[[MediaWiki_talk:Remembermypassword|Talk]] -
    -Remember my password across sessions. - -{{int:Remembermypassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removechecked&action=edit removechecked]
    -[[MediaWiki_talk:Removechecked|Talk]] -
    -Remove checked items from watchlist - -{{int:Removechecked}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removedwatch&action=edit removedwatch]
    -[[MediaWiki_talk:Removedwatch|Talk]] -
    -Removed from watchlist - -{{int:Removedwatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removedwatchtext&action=edit removedwatchtext]
    -[[MediaWiki_talk:Removedwatchtext|Talk]] -
    -The page "$1" has been removed from your watchlist. - -{{int:Removedwatchtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Removingchecked&action=edit removingchecked]
    -[[MediaWiki_talk:Removingchecked|Talk]] -
    -Removing requested items from watchlist... - -{{int:Removingchecked}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Resetprefs&action=edit resetprefs]
    -[[MediaWiki_talk:Resetprefs|Talk]] -
    -Reset preferences - -{{int:Resetprefs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Restorelink&action=edit restorelink]
    -[[MediaWiki_talk:Restorelink|Talk]] -
    -$1 deleted edits - -{{int:Restorelink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Resultsperpage&action=edit resultsperpage]
    -[[MediaWiki_talk:Resultsperpage|Talk]] -
    -Hits to show per page - -{{int:Resultsperpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Retrievedfrom&action=edit retrievedfrom]
    -[[MediaWiki_talk:Retrievedfrom|Talk]] -
    -Retrieved from "$1" - -{{int:Retrievedfrom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Returnto&action=edit returnto]
    -[[MediaWiki_talk:Returnto|Talk]] -
    -Return to $1. - -{{int:Returnto}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Retypenew&action=edit retypenew]
    -[[MediaWiki_talk:Retypenew|Talk]] -
    -Retype new password - -{{int:Retypenew}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reupload&action=edit reupload]
    -[[MediaWiki_talk:Reupload|Talk]] -
    -Re-upload - -{{int:Reupload}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reuploaddesc&action=edit reuploaddesc]
    -[[MediaWiki_talk:Reuploaddesc|Talk]] -
    -Return to the upload form. - -{{int:Reuploaddesc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Reverted&action=edit reverted]
    -[[MediaWiki_talk:Reverted|Talk]] -
    -Reverted to earlier revision - -{{int:Reverted}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revertimg&action=edit revertimg]
    -[[MediaWiki_talk:Revertimg|Talk]] -
    -rev - -{{int:Revertimg}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revertpage&action=edit revertpage]
    -[[MediaWiki_talk:Revertpage|Talk]] -
    -Reverted edit of $2, changed back to last version by $1 - -{{int:Revertpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revhistory&action=edit revhistory]
    -[[MediaWiki_talk:Revhistory|Talk]] -
    -Revision history - -{{int:Revhistory}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revisionasof&action=edit revisionasof]
    -[[MediaWiki_talk:Revisionasof|Talk]] -
    -Revision as of $1 - -{{int:Revisionasof}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revnotfound&action=edit revnotfound]
    -[[MediaWiki_talk:Revnotfound|Talk]] -
    -Revision not found - -{{int:Revnotfound}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Revnotfoundtext&action=edit revnotfoundtext]
    -[[MediaWiki_talk:Revnotfoundtext|Talk]] -
    -The old revision of the page you asked for could not be found. -Please check the URL you used to access this page. - - -{{int:Revnotfoundtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rfcurl&action=edit rfcurl]
    -[[MediaWiki_talk:Rfcurl|Talk]] -
    -http://www.faqs.org/rfcs/rfc$1.html - -{{int:Rfcurl}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rights&action=edit rights]
    -[[MediaWiki_talk:Rights|Talk]] -
    -Rights: - -{{int:Rights}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollback&action=edit rollback]
    -[[MediaWiki_talk:Rollback|Talk]] -
    -Roll back edits - -{{int:Rollback}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollback_short&action=edit rollback_short]
    -[[MediaWiki_talk:Rollback_short|Talk]] -
    -Rollback - -{{int:Rollback_short}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollbackfailed&action=edit rollbackfailed]
    -[[MediaWiki_talk:Rollbackfailed|Talk]] -
    -Rollback failed - -{{int:Rollbackfailed}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rollbacklink&action=edit rollbacklink]
    -[[MediaWiki_talk:Rollbacklink|Talk]] -
    -rollback - -{{int:Rollbacklink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Rows&action=edit rows]
    -[[MediaWiki_talk:Rows|Talk]] -
    -Rows - -{{int:Rows}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savearticle&action=edit savearticle]
    -[[MediaWiki_talk:Savearticle|Talk]] -
    -Save page - -{{int:Savearticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savedprefs&action=edit savedprefs]
    -[[MediaWiki_talk:Savedprefs|Talk]] -
    -Your preferences have been saved. - -{{int:Savedprefs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Savefile&action=edit savefile]
    -[[MediaWiki_talk:Savefile|Talk]] -
    -Save file - -{{int:Savefile}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Saveprefs&action=edit saveprefs]
    -[[MediaWiki_talk:Saveprefs|Talk]] -
    -Save preferences - -{{int:Saveprefs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Search&action=edit search]
    -[[MediaWiki_talk:Search|Talk]] -
    -Search - -{{int:Search}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchdisabled&action=edit searchdisabled]
    -[[MediaWiki_talk:Searchdisabled|Talk]] -
    -<p>Sorry! Full text search has been disabled temporarily, for performance reasons. In the meantime, you can use the Google search below, which may be out of date.</p> - -{{int:Searchdisabled}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchhelppage&action=edit searchhelppage]
    -[[MediaWiki_talk:Searchhelppage|Talk]] -
    -Wiktionary:Searching - -{{int:Searchhelppage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchingwikipedia&action=edit searchingwikipedia]
    -[[MediaWiki_talk:Searchingwikipedia|Talk]] -
    -Searching Wiktionary - -{{int:Searchingwikipedia}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchquery&action=edit searchquery]
    -[[MediaWiki_talk:Searchquery|Talk]] -
    -For query "$1" - -{{int:Searchquery}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresults&action=edit searchresults]
    -[[MediaWiki_talk:Searchresults|Talk]] -
    -Search results - -{{int:Searchresults}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresultshead&action=edit searchresultshead]
    -[[MediaWiki_talk:Searchresultshead|Talk]] -
    -Search result settings - -{{int:Searchresultshead}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Searchresulttext&action=edit searchresulttext]
    -[[MediaWiki_talk:Searchresulttext|Talk]] -
    -For more information about searching Wiktionary, see $1. - -{{int:Searchresulttext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sectionedit&action=edit sectionedit]
    -[[MediaWiki_talk:Sectionedit|Talk]] -
    - (section) - -{{int:Sectionedit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectnewerversionfordiff&action=edit selectnewerversionfordiff]
    -[[MediaWiki_talk:Selectnewerversionfordiff|Talk]] -
    -Select a newer version for comparison - -{{int:Selectnewerversionfordiff}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectolderversionfordiff&action=edit selectolderversionfordiff]
    -[[MediaWiki_talk:Selectolderversionfordiff|Talk]] -
    -Select an older version for comparison - -{{int:Selectolderversionfordiff}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selectonly&action=edit selectonly]
    -[[MediaWiki_talk:Selectonly|Talk]] -
    -Only read-only queries are allowed. - -{{int:Selectonly}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selflinks&action=edit selflinks]
    -[[MediaWiki_talk:Selflinks|Talk]] -
    -Pages with Self Links - -{{int:Selflinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Selflinkstext&action=edit selflinkstext]
    -[[MediaWiki_talk:Selflinkstext|Talk]] -
    -The following pages contain a link to themselves, which they should not. - -{{int:Selflinkstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Seriousxhtmlerrors&action=edit seriousxhtmlerrors]
    -[[MediaWiki_talk:Seriousxhtmlerrors|Talk]] -
    -There were serious xhtml markup errors detected by tidy. - -{{int:Seriousxhtmlerrors}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Servertime&action=edit servertime]
    -[[MediaWiki_talk:Servertime|Talk]] -
    -Server time is now - -{{int:Servertime}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Set_rights_fail&action=edit set_rights_fail]
    -[[MediaWiki_talk:Set_rights_fail|Talk]] -
    -<b>User rights for "$1" could not be set. (Did you enter the name correctly?)</b> - -{{int:Set_rights_fail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Set_user_rights&action=edit set_user_rights]
    -[[MediaWiki_talk:Set_user_rights|Talk]] -
    -Set user rights - -{{int:Set_user_rights}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Setbureaucratflag&action=edit setbureaucratflag]
    -[[MediaWiki_talk:Setbureaucratflag|Talk]] -
    -Set bureaucrat flag - -{{int:Setbureaucratflag}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Shortpages&action=edit shortpages]
    -[[MediaWiki_talk:Shortpages|Talk]] -
    -Short pages - -{{int:Shortpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Show&action=edit show]
    -[[MediaWiki_talk:Show|Talk]] -
    -show - -{{int:Show}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showhideminor&action=edit showhideminor]
    -[[MediaWiki_talk:Showhideminor|Talk]] -
    -$1 minor edits | $2 bots | $3 logged in users - -{{int:Showhideminor}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showingresults&action=edit showingresults]
    -[[MediaWiki_talk:Showingresults|Talk]] -
    -Showing below <b>$1</b> results starting with #<b>$2</b>. - -{{int:Showingresults}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showingresultsnum&action=edit showingresultsnum]
    -[[MediaWiki_talk:Showingresultsnum|Talk]] -
    -Showing below <b>$3</b> results starting with #<b>$2</b>. - -{{int:Showingresultsnum}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showlast&action=edit showlast]
    -[[MediaWiki_talk:Showlast|Talk]] -
    -Show last $1 images sorted $2. - -{{int:Showlast}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showpreview&action=edit showpreview]
    -[[MediaWiki_talk:Showpreview|Talk]] -
    -Show preview - -{{int:Showpreview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Showtoc&action=edit showtoc]
    -[[MediaWiki_talk:Showtoc|Talk]] -
    -show - -{{int:Showtoc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sig_tip&action=edit sig_tip]
    -[[MediaWiki_talk:Sig_tip|Talk]] -
    -Your signature with timestamp - -{{int:Sig_tip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitestats&action=edit sitestats]
    -[[MediaWiki_talk:Sitestats|Talk]] -
    -Site statistics - -{{int:Sitestats}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitestatstext&action=edit sitestatstext]
    -[[MediaWiki_talk:Sitestatstext|Talk]] -
    -There are '''$1''' total pages in the database. -This includes "talk" pages, pages about Wiktionary, minimal "stub" -pages, redirects, and others that probably don't qualify as content pages. -Excluding those, there are '''$2''' pages that are probably legitimate -content pages. - -There have been a total of '''$3''' page views, and '''$4''' page edits -since the wiki was setup. -That comes to '''$5''' average edits per page, and '''$6''' views per edit. - -{{int:Sitestatstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitesubtitle&action=edit sitesubtitle]
    -[[MediaWiki_talk:Sitesubtitle|Talk]] -
    -The Free Encyclopedia - -{{int:Sitesubtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitesupport&action=edit sitesupport]
    -[[MediaWiki_talk:Sitesupport|Talk]] -
    -Donations - -{{int:Sitesupport}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sitetitle&action=edit sitetitle]
    -[[MediaWiki_talk:Sitetitle|Talk]] -
    -Wiktionary - -{{int:Sitetitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Siteuser&action=edit siteuser]
    -[[MediaWiki_talk:Siteuser|Talk]] -
    -Wiktionary user $1 - -{{int:Siteuser}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Siteusers&action=edit siteusers]
    -[[MediaWiki_talk:Siteusers|Talk]] -
    -Wiktionary user(s) $1 - -{{int:Siteusers}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Skin&action=edit skin]
    -[[MediaWiki_talk:Skin|Talk]] -
    -Skin - -{{int:Skin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spamprotectiontext&action=edit spamprotectiontext]
    -[[MediaWiki_talk:Spamprotectiontext|Talk]] -
    -The page you wanted to save was blocked by the spam filter. This is probably caused by a link to an external site. - -You might want to check the following regular expression for patterns that are currently blocked: - -{{int:Spamprotectiontext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spamprotectiontitle&action=edit spamprotectiontitle]
    -[[MediaWiki_talk:Spamprotectiontitle|Talk]] -
    -Spam protection filter - -{{int:Spamprotectiontitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Specialpage&action=edit specialpage]
    -[[MediaWiki_talk:Specialpage|Talk]] -
    -Special Page - -{{int:Specialpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Specialpages&action=edit specialpages]
    -[[MediaWiki_talk:Specialpages|Talk]] -
    -Special pages - -{{int:Specialpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Spheading&action=edit spheading]
    -[[MediaWiki_talk:Spheading|Talk]] -
    -Special pages for all users - -{{int:Spheading}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sqlislogged&action=edit sqlislogged]
    -[[MediaWiki_talk:Sqlislogged|Talk]] -
    -Please note that all queries are logged. - -{{int:Sqlislogged}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sqlquery&action=edit sqlquery]
    -[[MediaWiki_talk:Sqlquery|Talk]] -
    -Enter query - -{{int:Sqlquery}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Statistics&action=edit statistics]
    -[[MediaWiki_talk:Statistics|Talk]] -
    -Statistics - -{{int:Statistics}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Storedversion&action=edit storedversion]
    -[[MediaWiki_talk:Storedversion|Talk]] -
    -Stored version - -{{int:Storedversion}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Stubthreshold&action=edit stubthreshold]
    -[[MediaWiki_talk:Stubthreshold|Talk]] -
    -Threshold for stub display - -{{int:Stubthreshold}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subcategories&action=edit subcategories]
    -[[MediaWiki_talk:Subcategories|Talk]] -
    -Subcategories - -{{int:Subcategories}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subject&action=edit subject]
    -[[MediaWiki_talk:Subject|Talk]] -
    -Subject/headline - -{{int:Subject}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Subjectpage&action=edit subjectpage]
    -[[MediaWiki_talk:Subjectpage|Talk]] -
    -View subject - -{{int:Subjectpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Successfulupload&action=edit successfulupload]
    -[[MediaWiki_talk:Successfulupload|Talk]] -
    -Successful upload - -{{int:Successfulupload}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Summary&action=edit summary]
    -[[MediaWiki_talk:Summary|Talk]] -
    -Summary - -{{int:Summary}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysopspheading&action=edit sysopspheading]
    -[[MediaWiki_talk:Sysopspheading|Talk]] -
    -For sysop use only - -{{int:Sysopspheading}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysoptext&action=edit sysoptext]
    -[[MediaWiki_talk:Sysoptext|Talk]] -
    -The action you have requested can only be -performed by users with "sysop" status. -See $1. - -{{int:Sysoptext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Sysoptitle&action=edit sysoptitle]
    -[[MediaWiki_talk:Sysoptitle|Talk]] -
    -Sysop access required - -{{int:Sysoptitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tableform&action=edit tableform]
    -[[MediaWiki_talk:Tableform|Talk]] -
    -table - -{{int:Tableform}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talk&action=edit talk]
    -[[MediaWiki_talk:Talk|Talk]] -
    -Discussion - -{{int:Talk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkexists&action=edit talkexists]
    -[[MediaWiki_talk:Talkexists|Talk]] -
    -The page itself was moved successfully, but the -talk page could not be moved because one already exists at the new -title. Please merge them manually. - -{{int:Talkexists}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpage&action=edit talkpage]
    -[[MediaWiki_talk:Talkpage|Talk]] -
    -Discuss this page - -{{int:Talkpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagemoved&action=edit talkpagemoved]
    -[[MediaWiki_talk:Talkpagemoved|Talk]] -
    -The corresponding talk page was also moved. - -{{int:Talkpagemoved}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagenotmoved&action=edit talkpagenotmoved]
    -[[MediaWiki_talk:Talkpagenotmoved|Talk]] -
    -The corresponding talk page was <strong>not</strong> moved. - -{{int:Talkpagenotmoved}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Talkpagetext&action=edit talkpagetext]
    -[[MediaWiki_talk:Talkpagetext|Talk]] -
    -<!-- MediaWiki:talkpagetext --> - -{{int:Talkpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Textboxsize&action=edit textboxsize]
    -[[MediaWiki_talk:Textboxsize|Talk]] -
    -Textbox dimensions - -{{int:Textboxsize}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Textmatches&action=edit textmatches]
    -[[MediaWiki_talk:Textmatches|Talk]] -
    -Page text matches - -{{int:Textmatches}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Thisisdeleted&action=edit thisisdeleted]
    -[[MediaWiki_talk:Thisisdeleted|Talk]] -
    -View or restore $1? - -{{int:Thisisdeleted}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Thumbnail-more&action=edit thumbnail-more]
    -[[MediaWiki_talk:Thumbnail-more|Talk]] -
    -Enlarge - -{{int:Thumbnail-more}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezonelegend&action=edit timezonelegend]
    -[[MediaWiki_talk:Timezonelegend|Talk]] -
    -Time zone - -{{int:Timezonelegend}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezoneoffset&action=edit timezoneoffset]
    -[[MediaWiki_talk:Timezoneoffset|Talk]] -
    -Offset - -{{int:Timezoneoffset}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Timezonetext&action=edit timezonetext]
    -[[MediaWiki_talk:Timezonetext|Talk]] -
    -Enter number of hours your local time differs -from server time (UTC). - -{{int:Timezonetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Titlematches&action=edit titlematches]
    -[[MediaWiki_talk:Titlematches|Talk]] -
    -Article title matches - -{{int:Titlematches}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Toc&action=edit toc]
    -[[MediaWiki_talk:Toc|Talk]] -
    -Table of contents - -{{int:Toc}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Toolbox&action=edit toolbox]
    -[[MediaWiki_talk:Toolbox|Talk]] -
    -Toolbox - -{{int:Toolbox}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-addsection&action=edit tooltip-addsection]
    -[[MediaWiki_talk:Tooltip-addsection|Talk]] -
    -Add a comment to this page. [alt-+] - -{{int:Tooltip-addsection}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-anontalk&action=edit tooltip-anontalk]
    -[[MediaWiki_talk:Tooltip-anontalk|Talk]] -
    -Discussion about edits from this ip address [alt-n] - -{{int:Tooltip-anontalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-anonuserpage&action=edit tooltip-anonuserpage]
    -[[MediaWiki_talk:Tooltip-anonuserpage|Talk]] -
    -The user page for the ip you're editing as [alt-.] - -{{int:Tooltip-anonuserpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-article&action=edit tooltip-article]
    -[[MediaWiki_talk:Tooltip-article|Talk]] -
    -View the content page [alt-a] - -{{int:Tooltip-article}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-atom&action=edit tooltip-atom]
    -[[MediaWiki_talk:Tooltip-atom|Talk]] -
    -Atom feed for this page - -{{int:Tooltip-atom}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-compareselectedversions&action=edit tooltip-compareselectedversions]
    -[[MediaWiki_talk:Tooltip-compareselectedversions|Talk]] -
    -See the differences between the two selected versions of this page. [alt-v] - -{{int:Tooltip-compareselectedversions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-contributions&action=edit tooltip-contributions]
    -[[MediaWiki_talk:Tooltip-contributions|Talk]] -
    -View the list of contributions of this user - -{{int:Tooltip-contributions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-currentevents&action=edit tooltip-currentevents]
    -[[MediaWiki_talk:Tooltip-currentevents|Talk]] -
    -Find background information on current events - -{{int:Tooltip-currentevents}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-delete&action=edit tooltip-delete]
    -[[MediaWiki_talk:Tooltip-delete|Talk]] -
    -Delete this page [alt-d] - -{{int:Tooltip-delete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-edit&action=edit tooltip-edit]
    -[[MediaWiki_talk:Tooltip-edit|Talk]] -
    -You can edit this page. Please use the preview button before saving. [alt-e] - -{{int:Tooltip-edit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-emailuser&action=edit tooltip-emailuser]
    -[[MediaWiki_talk:Tooltip-emailuser|Talk]] -
    -Send a mail to this user - -{{int:Tooltip-emailuser}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-help&action=edit tooltip-help]
    -[[MediaWiki_talk:Tooltip-help|Talk]] -
    -The place to find out. - -{{int:Tooltip-help}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-history&action=edit tooltip-history]
    -[[MediaWiki_talk:Tooltip-history|Talk]] -
    -Past versions of this page, [alt-h] - -{{int:Tooltip-history}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-login&action=edit tooltip-login]
    -[[MediaWiki_talk:Tooltip-login|Talk]] -
    -You are encouraged to log in, it is not mandatory however. [alt-o] - -{{int:Tooltip-login}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-logout&action=edit tooltip-logout]
    -[[MediaWiki_talk:Tooltip-logout|Talk]] -
    -Log out [alt-o] - -{{int:Tooltip-logout}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mainpage&action=edit tooltip-mainpage]
    -[[MediaWiki_talk:Tooltip-mainpage|Talk]] -
    -Visit the Main Page [alt-z] - -{{int:Tooltip-mainpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-minoredit&action=edit tooltip-minoredit]
    -[[MediaWiki_talk:Tooltip-minoredit|Talk]] -
    -Mark this as a minor edit [alt-i] - -{{int:Tooltip-minoredit}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-move&action=edit tooltip-move]
    -[[MediaWiki_talk:Tooltip-move|Talk]] -
    -Move this page [alt-m] - -{{int:Tooltip-move}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mycontris&action=edit tooltip-mycontris]
    -[[MediaWiki_talk:Tooltip-mycontris|Talk]] -
    -List of my contributions [alt-y] - -{{int:Tooltip-mycontris}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-mytalk&action=edit tooltip-mytalk]
    -[[MediaWiki_talk:Tooltip-mytalk|Talk]] -
    -My talk page [alt-n] - -{{int:Tooltip-mytalk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-nomove&action=edit tooltip-nomove]
    -[[MediaWiki_talk:Tooltip-nomove|Talk]] -
    -You don't have the permissions to move this page - -{{int:Tooltip-nomove}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-portal&action=edit tooltip-portal]
    -[[MediaWiki_talk:Tooltip-portal|Talk]] -
    -About the project, what you can do, where to find things - -{{int:Tooltip-portal}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-preferences&action=edit tooltip-preferences]
    -[[MediaWiki_talk:Tooltip-preferences|Talk]] -
    -My preferences - -{{int:Tooltip-preferences}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-preview&action=edit tooltip-preview]
    -[[MediaWiki_talk:Tooltip-preview|Talk]] -
    -Preview your changes, please use this before saving! [alt-p] - -{{int:Tooltip-preview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-protect&action=edit tooltip-protect]
    -[[MediaWiki_talk:Tooltip-protect|Talk]] -
    -Protect this page [alt-=] - -{{int:Tooltip-protect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-randompage&action=edit tooltip-randompage]
    -[[MediaWiki_talk:Tooltip-randompage|Talk]] -
    -Load a random page [alt-x] - -{{int:Tooltip-randompage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-recentchanges&action=edit tooltip-recentchanges]
    -[[MediaWiki_talk:Tooltip-recentchanges|Talk]] -
    -The list of recent changes in the wiki. [alt-r] - -{{int:Tooltip-recentchanges}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-recentchangeslinked&action=edit tooltip-recentchangeslinked]
    -[[MediaWiki_talk:Tooltip-recentchangeslinked|Talk]] -
    -Recent changes in pages linking to this page [alt-c] - -{{int:Tooltip-recentchangeslinked}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-rss&action=edit tooltip-rss]
    -[[MediaWiki_talk:Tooltip-rss|Talk]] -
    -RSS feed for this page - -{{int:Tooltip-rss}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-save&action=edit tooltip-save]
    -[[MediaWiki_talk:Tooltip-save|Talk]] -
    -Save your changes [alt-s] - -{{int:Tooltip-save}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-search&action=edit tooltip-search]
    -[[MediaWiki_talk:Tooltip-search|Talk]] -
    -Search this wiki [alt-f] - -{{int:Tooltip-search}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-sitesupport&action=edit tooltip-sitesupport]
    -[[MediaWiki_talk:Tooltip-sitesupport|Talk]] -
    -Support Wiktionary - -{{int:Tooltip-sitesupport}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-specialpage&action=edit tooltip-specialpage]
    -[[MediaWiki_talk:Tooltip-specialpage|Talk]] -
    -This is a special page, you can't edit the page itself. - -{{int:Tooltip-specialpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-specialpages&action=edit tooltip-specialpages]
    -[[MediaWiki_talk:Tooltip-specialpages|Talk]] -
    -List of all special pages [alt-q] - -{{int:Tooltip-specialpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-talk&action=edit tooltip-talk]
    -[[MediaWiki_talk:Tooltip-talk|Talk]] -
    -Discussion about the content page [alt-t] - -{{int:Tooltip-talk}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-undelete&action=edit tooltip-undelete]
    -[[MediaWiki_talk:Tooltip-undelete|Talk]] -
    -Restore the $1 edits done to this page before it was deleted [alt-d] - -{{int:Tooltip-undelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-unwatch&action=edit tooltip-unwatch]
    -[[MediaWiki_talk:Tooltip-unwatch|Talk]] -
    -Remove this page from your watchlist [alt-w] - -{{int:Tooltip-unwatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-upload&action=edit tooltip-upload]
    -[[MediaWiki_talk:Tooltip-upload|Talk]] -
    -Upload images or media files [alt-u] - -{{int:Tooltip-upload}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-userpage&action=edit tooltip-userpage]
    -[[MediaWiki_talk:Tooltip-userpage|Talk]] -
    -My user page [alt-.] - -{{int:Tooltip-userpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-viewsource&action=edit tooltip-viewsource]
    -[[MediaWiki_talk:Tooltip-viewsource|Talk]] -
    -This page is protected. You can view its source. [alt-e] - -{{int:Tooltip-viewsource}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-watch&action=edit tooltip-watch]
    -[[MediaWiki_talk:Tooltip-watch|Talk]] -
    -Add this page to your watchlist [alt-w] - -{{int:Tooltip-watch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-watchlist&action=edit tooltip-watchlist]
    -[[MediaWiki_talk:Tooltip-watchlist|Talk]] -
    -The list of pages you're monitoring for changes. [alt-l] - -{{int:Tooltip-watchlist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Tooltip-whatlinkshere&action=edit tooltip-whatlinkshere]
    -[[MediaWiki_talk:Tooltip-whatlinkshere|Talk]] -
    -List of all wiki pages that link here [alt-b] - -{{int:Tooltip-whatlinkshere}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uclinks&action=edit uclinks]
    -[[MediaWiki_talk:Uclinks|Talk]] -
    -View the last $1 changes; view the last $2 days. - -{{int:Uclinks}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Ucnote&action=edit ucnote]
    -[[MediaWiki_talk:Ucnote|Talk]] -
    -Below are this user's last <b>$1</b> changes in the last <b>$2</b> days. - -{{int:Ucnote}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uctop&action=edit uctop]
    -[[MediaWiki_talk:Uctop|Talk]] -
    - (top) - -{{int:Uctop}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblockip&action=edit unblockip]
    -[[MediaWiki_talk:Unblockip|Talk]] -
    -Unblock user - -{{int:Unblockip}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblockiptext&action=edit unblockiptext]
    -[[MediaWiki_talk:Unblockiptext|Talk]] -
    -Use the form below to restore write access -to a previously blocked IP address or username. - -{{int:Unblockiptext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblocklink&action=edit unblocklink]
    -[[MediaWiki_talk:Unblocklink|Talk]] -
    -unblock - -{{int:Unblocklink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unblocklogentry&action=edit unblocklogentry]
    -[[MediaWiki_talk:Unblocklogentry|Talk]] -
    -unblocked "$1" - -{{int:Unblocklogentry}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undelete&action=edit undelete]
    -[[MediaWiki_talk:Undelete|Talk]] -
    -Restore deleted page - -{{int:Undelete}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undelete_short&action=edit undelete_short]
    -[[MediaWiki_talk:Undelete_short|Talk]] -
    -Undelete $1 edits - -{{int:Undelete_short}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletearticle&action=edit undeletearticle]
    -[[MediaWiki_talk:Undeletearticle|Talk]] -
    -Restore deleted page - -{{int:Undeletearticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletebtn&action=edit undeletebtn]
    -[[MediaWiki_talk:Undeletebtn|Talk]] -
    -Restore! - -{{int:Undeletebtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletedarticle&action=edit undeletedarticle]
    -[[MediaWiki_talk:Undeletedarticle|Talk]] -
    -restored "$1" - -{{int:Undeletedarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletedtext&action=edit undeletedtext]
    -[[MediaWiki_talk:Undeletedtext|Talk]] -
    -[[$1]] has been successfully restored. -See [[Wiktionary:Deletion_log]] for a record of recent deletions and restorations. - -{{int:Undeletedtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletehistory&action=edit undeletehistory]
    -[[MediaWiki_talk:Undeletehistory|Talk]] -
    -If you restore the page, all revisions will be restored to the history. -If a new page with the same name has been created since the deletion, the restored -revisions will appear in the prior history, and the current revision of the live page -will not be automatically replaced. - -{{int:Undeletehistory}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletepage&action=edit undeletepage]
    -[[MediaWiki_talk:Undeletepage|Talk]] -
    -View and restore deleted pages - -{{int:Undeletepage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeletepagetext&action=edit undeletepagetext]
    -[[MediaWiki_talk:Undeletepagetext|Talk]] -
    -The following pages have been deleted but are still in the archive and -can be restored. The archive may be periodically cleaned out. - -{{int:Undeletepagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeleterevision&action=edit undeleterevision]
    -[[MediaWiki_talk:Undeleterevision|Talk]] -
    -Deleted revision as of $1 - -{{int:Undeleterevision}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Undeleterevisions&action=edit undeleterevisions]
    -[[MediaWiki_talk:Undeleterevisions|Talk]] -
    -$1 revisions archived - -{{int:Undeleterevisions}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unexpected&action=edit unexpected]
    -[[MediaWiki_talk:Unexpected|Talk]] -
    -Unexpected value: "$1"="$2". - -{{int:Unexpected}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockbtn&action=edit unlockbtn]
    -[[MediaWiki_talk:Unlockbtn|Talk]] -
    -Unlock database - -{{int:Unlockbtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockconfirm&action=edit unlockconfirm]
    -[[MediaWiki_talk:Unlockconfirm|Talk]] -
    -Yes, I really want to unlock the database. - -{{int:Unlockconfirm}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdb&action=edit unlockdb]
    -[[MediaWiki_talk:Unlockdb|Talk]] -
    -Unlock database - -{{int:Unlockdb}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbsuccesssub&action=edit unlockdbsuccesssub]
    -[[MediaWiki_talk:Unlockdbsuccesssub|Talk]] -
    -Database lock removed - -{{int:Unlockdbsuccesssub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbsuccesstext&action=edit unlockdbsuccesstext]
    -[[MediaWiki_talk:Unlockdbsuccesstext|Talk]] -
    -The database has been unlocked. - -{{int:Unlockdbsuccesstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unlockdbtext&action=edit unlockdbtext]
    -[[MediaWiki_talk:Unlockdbtext|Talk]] -
    -Unlocking the database will restore the ability of all -users to edit pages, change their preferences, edit their watchlists, and -other things requiring changes in the database. -Please confirm that this is what you intend to do. - -{{int:Unlockdbtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotect&action=edit unprotect]
    -[[MediaWiki_talk:Unprotect|Talk]] -
    -Unprotect - -{{int:Unprotect}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectcomment&action=edit unprotectcomment]
    -[[MediaWiki_talk:Unprotectcomment|Talk]] -
    -Reason for unprotecting - -{{int:Unprotectcomment}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectedarticle&action=edit unprotectedarticle]
    -[[MediaWiki_talk:Unprotectedarticle|Talk]] -
    -unprotected [[$1]] - -{{int:Unprotectedarticle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectsub&action=edit unprotectsub]
    -[[MediaWiki_talk:Unprotectsub|Talk]] -
    -(Unprotecting "$1") - -{{int:Unprotectsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unprotectthispage&action=edit unprotectthispage]
    -[[MediaWiki_talk:Unprotectthispage|Talk]] -
    -Unprotect this page - -{{int:Unprotectthispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unusedimages&action=edit unusedimages]
    -[[MediaWiki_talk:Unusedimages|Talk]] -
    -Unused images - -{{int:Unusedimages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unusedimagestext&action=edit unusedimagestext]
    -[[MediaWiki_talk:Unusedimagestext|Talk]] -
    -<p>Please note that other web sites may link to an image with -a direct URL, and so may still be listed here despite being -in active use. - -{{int:Unusedimagestext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unwatch&action=edit unwatch]
    -[[MediaWiki_talk:Unwatch|Talk]] -
    -Unwatch - -{{int:Unwatch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Unwatchthispage&action=edit unwatchthispage]
    -[[MediaWiki_talk:Unwatchthispage|Talk]] -
    -Stop watching - -{{int:Unwatchthispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Updated&action=edit updated]
    -[[MediaWiki_talk:Updated|Talk]] -
    -(Updated) - -{{int:Updated}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Upload&action=edit upload]
    -[[MediaWiki_talk:Upload|Talk]] -
    -Upload file - -{{int:Upload}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadbtn&action=edit uploadbtn]
    -[[MediaWiki_talk:Uploadbtn|Talk]] -
    -Upload file - -{{int:Uploadbtn}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploaddisabled&action=edit uploaddisabled]
    -[[MediaWiki_talk:Uploaddisabled|Talk]] -
    -Sorry, uploading is disabled. - -{{int:Uploaddisabled}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadedfiles&action=edit uploadedfiles]
    -[[MediaWiki_talk:Uploadedfiles|Talk]] -
    -Uploaded files - -{{int:Uploadedfiles}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadedimage&action=edit uploadedimage]
    -[[MediaWiki_talk:Uploadedimage|Talk]] -
    -uploaded "$1" - -{{int:Uploadedimage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploaderror&action=edit uploaderror]
    -[[MediaWiki_talk:Uploaderror|Talk]] -
    -Upload error - -{{int:Uploaderror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadfile&action=edit uploadfile]
    -[[MediaWiki_talk:Uploadfile|Talk]] -
    -Upload images, sounds, documents etc. - -{{int:Uploadfile}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlink&action=edit uploadlink]
    -[[MediaWiki_talk:Uploadlink|Talk]] -
    -Upload images - -{{int:Uploadlink}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlog&action=edit uploadlog]
    -[[MediaWiki_talk:Uploadlog|Talk]] -
    -upload log - -{{int:Uploadlog}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlogpage&action=edit uploadlogpage]
    -[[MediaWiki_talk:Uploadlogpage|Talk]] -
    -Upload_log - -{{int:Uploadlogpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadlogpagetext&action=edit uploadlogpagetext]
    -[[MediaWiki_talk:Uploadlogpagetext|Talk]] -
    -Below is a list of the most recent file uploads. -All times shown are server time (UTC). -<ul> -</ul> - - -{{int:Uploadlogpagetext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadnologin&action=edit uploadnologin]
    -[[MediaWiki_talk:Uploadnologin|Talk]] -
    -Not logged in - -{{int:Uploadnologin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadnologintext&action=edit uploadnologintext]
    -[[MediaWiki_talk:Uploadnologintext|Talk]] -
    -You must be <a href="/wiki/Special:Userlogin">logged in</a> -to upload files. - -{{int:Uploadnologintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadtext&action=edit uploadtext]
    -[[MediaWiki_talk:Uploadtext|Talk]] -
    -<strong>STOP!</strong> Before you upload here, -make sure to read and follow the <a href="/wiki/Special:Image_use_policy">image use policy</a>. -<p>If a file with the name you are specifying already -exists on the wiki, it'll be replaced without warning. -So unless you mean to update a file, it's a good idea -to first check if such a file exists. -<p>To view or search previously uploaded images, -go to the <a href="/wiki/Special:Imagelist">list of uploaded images</a>. -Uploads and deletions are logged on the <a href="/wiki/Wiktionary:Upload_log">upload log</a>. -</p><p>Use the form below to upload new image files for use in -illustrating your pages. -On most browsers, you will see a "Browse..." button, which will -bring up your operating system's standard file open dialog. -Choosing a file will fill the name of that file into the text -field next to the button. -You must also check the box affirming that you are not -violating any copyrights by uploading the file. -Press the "Upload" button to finish the upload. -This may take some time if you have a slow internet connection. -<p>The preferred formats are JPEG for photographic images, PNG -for drawings and other iconic images, and OGG for sounds. -Please name your files descriptively to avoid confusion. -To include the image in a page, use a link in the form -<b>[[Image:file.jpg]]</b> or <b>[[Image:file.png|alt text]]</b> -or <b>[[Media:file.ogg]]</b> for sounds. -<p>Please note that as with wiki pages, others may edit or -delete your uploads if they think it serves the project, and -you may be blocked from uploading if you abuse the system. - -{{int:Uploadtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Uploadwarning&action=edit uploadwarning]
    -[[MediaWiki_talk:Uploadwarning|Talk]] -
    -Upload warning - -{{int:Uploadwarning}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:User_rights_set&action=edit user_rights_set]
    -[[MediaWiki_talk:User_rights_set|Talk]] -
    -<b>User rights for "$1" updated</b> - -{{int:User_rights_set}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercssjs&action=edit usercssjs]
    -[[MediaWiki_talk:Usercssjs|Talk]] -
    -'''Note:''' After saving, you have to tell your bowser to get the new version: '''Mozilla:''' click ''reload''(or ''ctrl-r''), '''IE / Opera:''' ''ctrl-f5'', '''Safari:''' ''cmd-r'', '''Konqueror''' ''ctrl-r''. - -{{int:Usercssjs}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercssjsyoucanpreview&action=edit usercssjsyoucanpreview]
    -[[MediaWiki_talk:Usercssjsyoucanpreview|Talk]] -
    -<strong>Tip:</strong> Use the 'Show preview' button to test your new css/js before saving. - -{{int:Usercssjsyoucanpreview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usercsspreview&action=edit usercsspreview]
    -[[MediaWiki_talk:Usercsspreview|Talk]] -
    -'''Remember that you are only previewing your user css, it has not yet been saved!''' - -{{int:Usercsspreview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userexists&action=edit userexists]
    -[[MediaWiki_talk:Userexists|Talk]] -
    -The user name you entered is already in use. Please choose a different name. - -{{int:Userexists}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userjspreview&action=edit userjspreview]
    -[[MediaWiki_talk:Userjspreview|Talk]] -
    -'''Remember that you are only testing/previewing your user javascript, it has not yet been saved!''' - -{{int:Userjspreview}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userlogin&action=edit userlogin]
    -[[MediaWiki_talk:Userlogin|Talk]] -
    -Log in - -{{int:Userlogin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userlogout&action=edit userlogout]
    -[[MediaWiki_talk:Userlogout|Talk]] -
    -Log out - -{{int:Userlogout}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Usermailererror&action=edit usermailererror]
    -[[MediaWiki_talk:Usermailererror|Talk]] -
    -Mail object returned error: - -{{int:Usermailererror}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userpage&action=edit userpage]
    -[[MediaWiki_talk:Userpage|Talk]] -
    -View user page - -{{int:Userpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userstats&action=edit userstats]
    -[[MediaWiki_talk:Userstats|Talk]] -
    -User statistics - -{{int:Userstats}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Userstatstext&action=edit userstatstext]
    -[[MediaWiki_talk:Userstatstext|Talk]] -
    -There are '''$1''' registered users. -'''$2''' of these are administrators (see $3). - -{{int:Userstatstext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Version&action=edit version]
    -[[MediaWiki_talk:Version|Talk]] -
    -Version - -{{int:Version}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewcount&action=edit viewcount]
    -[[MediaWiki_talk:Viewcount|Talk]] -
    -This page has been accessed $1 times. - -{{int:Viewcount}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewprevnext&action=edit viewprevnext]
    -[[MediaWiki_talk:Viewprevnext|Talk]] -
    -View ($1) ($2) ($3). - -{{int:Viewprevnext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewsource&action=edit viewsource]
    -[[MediaWiki_talk:Viewsource|Talk]] -
    -View source - -{{int:Viewsource}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Viewtalkpage&action=edit viewtalkpage]
    -[[MediaWiki_talk:Viewtalkpage|Talk]] -
    -View discussion - -{{int:Viewtalkpage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wantedpages&action=edit wantedpages]
    -[[MediaWiki_talk:Wantedpages|Talk]] -
    -Wanted pages - -{{int:Wantedpages}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watch&action=edit watch]
    -[[MediaWiki_talk:Watch|Talk]] -
    -Watch - -{{int:Watch}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchdetails&action=edit watchdetails]
    -[[MediaWiki_talk:Watchdetails|Talk]] -
    -($1 pages watched not counting talk pages; -$2 total pages edited since cutoff; -$3... -<a href='$4'>show and edit complete list</a>.) - -{{int:Watchdetails}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watcheditlist&action=edit watcheditlist]
    -[[MediaWiki_talk:Watcheditlist|Talk]] -
    -Here's an alphabetical list of your -watched pages. Check the boxes of pages you want to remove -from your watchlist and click the 'remove checked' button -at the bottom of the screen. - -{{int:Watcheditlist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlist&action=edit watchlist]
    -[[MediaWiki_talk:Watchlist|Talk]] -
    -My watchlist - -{{int:Watchlist}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlistcontains&action=edit watchlistcontains]
    -[[MediaWiki_talk:Watchlistcontains|Talk]] -
    -Your watchlist contains $1 pages. - -{{int:Watchlistcontains}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchlistsub&action=edit watchlistsub]
    -[[MediaWiki_talk:Watchlistsub|Talk]] -
    -(for user "$1") - -{{int:Watchlistsub}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchmethod-list&action=edit watchmethod-list]
    -[[MediaWiki_talk:Watchmethod-list|Talk]] -
    -checking watched pages for recent edits - -{{int:Watchmethod-list}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchmethod-recent&action=edit watchmethod-recent]
    -[[MediaWiki_talk:Watchmethod-recent|Talk]] -
    -checking recent edits for watched pages - -{{int:Watchmethod-recent}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnochange&action=edit watchnochange]
    -[[MediaWiki_talk:Watchnochange|Talk]] -
    -None of your watched items were edited in the time period displayed. - -{{int:Watchnochange}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnologin&action=edit watchnologin]
    -[[MediaWiki_talk:Watchnologin|Talk]] -
    -Not logged in - -{{int:Watchnologin}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchnologintext&action=edit watchnologintext]
    -[[MediaWiki_talk:Watchnologintext|Talk]] -
    -You must be <a href="/wiki/Special:Userlogin">logged in</a> -to modify your watchlist. - -{{int:Watchnologintext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchthis&action=edit watchthis]
    -[[MediaWiki_talk:Watchthis|Talk]] -
    -Watch this page - -{{int:Watchthis}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Watchthispage&action=edit watchthispage]
    -[[MediaWiki_talk:Watchthispage|Talk]] -
    -Watch this page - -{{int:Watchthispage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Welcomecreation&action=edit welcomecreation]
    -[[MediaWiki_talk:Welcomecreation|Talk]] -
    -<h2>Welcome, $1!</h2><p>Your account has been created. -Don't forget to change your Wiktionary preferences. - -{{int:Welcomecreation}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whatlinkshere&action=edit whatlinkshere]
    -[[MediaWiki_talk:Whatlinkshere|Talk]] -
    -What links here - -{{int:Whatlinkshere}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistacctext&action=edit whitelistacctext]
    -[[MediaWiki_talk:Whitelistacctext|Talk]] -
    -To be allowed to create accounts in this Wiki you have to [[Special:Userlogin|log]] in and have the appropriate permissions. - -{{int:Whitelistacctext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistacctitle&action=edit whitelistacctitle]
    -[[MediaWiki_talk:Whitelistacctitle|Talk]] -
    -You are not allowed to create an account - -{{int:Whitelistacctitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistedittext&action=edit whitelistedittext]
    -[[MediaWiki_talk:Whitelistedittext|Talk]] -
    -You have to [[Special:Userlogin|login]] to edit pages. - -{{int:Whitelistedittext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistedittitle&action=edit whitelistedittitle]
    -[[MediaWiki_talk:Whitelistedittitle|Talk]] -
    -Login required to edit - -{{int:Whitelistedittitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistreadtext&action=edit whitelistreadtext]
    -[[MediaWiki_talk:Whitelistreadtext|Talk]] -
    -You have to [[Special:Userlogin|login]] to read pages. - -{{int:Whitelistreadtext}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Whitelistreadtitle&action=edit whitelistreadtitle]
    -[[MediaWiki_talk:Whitelistreadtitle|Talk]] -
    -Login required to read - -{{int:Whitelistreadtitle}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wikipediapage&action=edit wikipediapage]
    -[[MediaWiki_talk:Wikipediapage|Talk]] -
    -View project page - -{{int:Wikipediapage}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wikititlesuffix&action=edit wikititlesuffix]
    -[[MediaWiki_talk:Wikititlesuffix|Talk]] -
    -Wiktionary - -{{int:Wikititlesuffix}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlnote&action=edit wlnote]
    -[[MediaWiki_talk:Wlnote|Talk]] -
    -Below are the last $1 changes in the last <b>$2</b> hours. - -{{int:Wlnote}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlsaved&action=edit wlsaved]
    -[[MediaWiki_talk:Wlsaved|Talk]] -
    -This is a saved version of your watchlist. - -{{int:Wlsaved}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wlshowlast&action=edit wlshowlast]
    -[[MediaWiki_talk:Wlshowlast|Talk]] -
    -Show last $1 hours $2 days $3 - -{{int:Wlshowlast}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wrong_wfQuery_params&action=edit wrong_wfQuery_params]
    -[[MediaWiki_talk:Wrong_wfQuery_params|Talk]] -
    -Incorrect parameters to wfQuery()<br /> -Function: $1<br /> -Query: $2 - - -{{int:Wrong_wfQuery_params}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Wrongpassword&action=edit wrongpassword]
    -[[MediaWiki_talk:Wrongpassword|Talk]] -
    -The password you entered is incorrect. Please try again. - -{{int:Wrongpassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourdiff&action=edit yourdiff]
    -[[MediaWiki_talk:Yourdiff|Talk]] -
    -Differences - -{{int:Yourdiff}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Youremail&action=edit youremail]
    -[[MediaWiki_talk:Youremail|Talk]] -
    -Your email* - -{{int:Youremail}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourname&action=edit yourname]
    -[[MediaWiki_talk:Yourname|Talk]] -
    -Your user name - -{{int:Yourname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yournick&action=edit yournick]
    -[[MediaWiki_talk:Yournick|Talk]] -
    -Your nickname (for signatures) - -{{int:Yournick}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourpassword&action=edit yourpassword]
    -[[MediaWiki_talk:Yourpassword|Talk]] -
    -Your password - -{{int:Yourpassword}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourpasswordagain&action=edit yourpasswordagain]
    -[[MediaWiki_talk:Yourpasswordagain|Talk]] -
    -Retype password - -{{int:Yourpasswordagain}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourrealname&action=edit yourrealname]
    -[[MediaWiki_talk:Yourrealname|Talk]] -
    -Your real name* - -{{int:Yourrealname}} -
    -[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Yourtext&action=edit yourtext]
    -[[MediaWiki_talk:Yourtext|Talk]] -
    -Your text - -{{int:Yourtext}} -
    - diff --git a/tests/parser/preprocess/Factorial.expected b/tests/parser/preprocess/Factorial.expected deleted file mode 100644 index a10fd6ca..00000000 --- a/tests/parser/preprocess/Factorial.expected +++ /dev/null @@ -1,17 +0,0 @@ -1011*011*021*031*041*051*061*071*081*091*101*111*121*131*141*151*161*171*181*191*201*211*221*231*241*251*261*271*281*291*301*311*321*331*341*351*361*371*381*391*401*411*421*431*441*451*461*471*481*491*501*511*521*531*541*551*561*571*581*591*601*611*621*631*641*651*661*671*681*691*701*711*721*731*741*751*761*771*781*791*801*811*821*831*841*851*861*871*881*891*901*911*921*931*941*951*961*971*981*99<noinclude> - -This template finds the [[factorial]] of a number. To use it, enter:<br /> -<code><nowiki></nowiki></code><br /> -The input must be a positive interger smaller than 100 (better than most calculators, which go up to only 69). This template works by repeating conditional multiplications. Examples:<br /> -*<nowiki></nowiki> gives -*<nowiki></nowiki> gives -*<nowiki></nowiki> gives -*<nowiki></nowiki> gives -*<nowiki></nowiki> gives -*<nowiki></nowiki> gives (invalid input) -*<nowiki></nowiki> gives (invalid input) - -[[Category:Mathematical templates|]] -</noinclude> - - \ No newline at end of file diff --git a/tests/parser/preprocess/Factorial.txt b/tests/parser/preprocess/Factorial.txt deleted file mode 100644 index 316f0792..00000000 --- a/tests/parser/preprocess/Factorial.txt +++ /dev/null @@ -1,16 +0,0 @@ -{{#expr:{{#ifeq:{{#expr:{{{1}}}>=00}}|1|01{{#ifeq:{{#expr:{{{1}}}>=01}}|1|*01{{#ifeq:{{#expr:{{{1}}}>=02}}|1|*02{{#ifeq:{{#expr:{{{1}}}>=03}}|1|*03{{#ifeq:{{#expr:{{{1}}}>=04}}|1|*04{{#ifeq:{{#expr:{{{1}}}>=05}}|1|*05{{#ifeq:{{#expr:{{{1}}}>=06}}|1|*06{{#ifeq:{{#expr:{{{1}}}>=07}}|1|*07{{#ifeq:{{#expr:{{{1}}}>=08}}|1|*08{{#ifeq:{{#expr:{{{1}}}>=09}}|1|*09{{#ifeq:{{#expr:{{{1}}}>=10}}|1|*10{{#ifeq:{{#expr:{{{1}}}>=11}}|1|*11{{#ifeq:{{#expr:{{{1}}}>=12}}|1|*12{{#ifeq:{{#expr:{{{1}}}>=13}}|1|*13{{#ifeq:{{#expr:{{{1}}}>=14}}|1|*14{{#ifeq:{{#expr:{{{1}}}>=15}}|1|*15{{#ifeq:{{#expr:{{{1}}}>=16}}|1|*16{{#ifeq:{{#expr:{{{1}}}>=17}}|1|*17{{#ifeq:{{#expr:{{{1}}}>=18}}|1|*18{{#ifeq:{{#expr:{{{1}}}>=19}}|1|*19{{#ifeq:{{#expr:{{{1}}}>=20}}|1|*20{{#ifeq:{{#expr:{{{1}}}>=21}}|1|*21{{#ifeq:{{#expr:{{{1}}}>=22}}|1|*22{{#ifeq:{{#expr:{{{1}}}>=23}}|1|*23{{#ifeq:{{#expr:{{{1}}}>=24}}|1|*24{{#ifeq:{{#expr:{{{1}}}>=25}}|1|*25{{#ifeq:{{#expr:{{{1}}}>=26}}|1|*26{{#ifeq:{{#expr:{{{1}}}>=27}}|1|*27{{#ifeq:{{#expr:{{{1}}}>=28}}|1|*28{{#ifeq:{{#expr:{{{1}}}>=29}}|1|*29{{#ifeq:{{#expr:{{{1}}}>=30}}|1|*30{{#ifeq:{{#expr:{{{1}}}>=31}}|1|*31{{#ifeq:{{#expr:{{{1}}}>=32}}|1|*32{{#ifeq:{{#expr:{{{1}}}>=33}}|1|*33{{#ifeq:{{#expr:{{{1}}}>=34}}|1|*34{{#ifeq:{{#expr:{{{1}}}>=35}}|1|*35{{#ifeq:{{#expr:{{{1}}}>=36}}|1|*36{{#ifeq:{{#expr:{{{1}}}>=37}}|1|*37{{#ifeq:{{#expr:{{{1}}}>=38}}|1|*38{{#ifeq:{{#expr:{{{1}}}>=39}}|1|*39{{#ifeq:{{#expr:{{{1}}}>=40}}|1|*40{{#ifeq:{{#expr:{{{1}}}>=41}}|1|*41{{#ifeq:{{#expr:{{{1}}}>=42}}|1|*42{{#ifeq:{{#expr:{{{1}}}>=43}}|1|*43{{#ifeq:{{#expr:{{{1}}}>=44}}|1|*44{{#ifeq:{{#expr:{{{1}}}>=45}}|1|*45{{#ifeq:{{#expr:{{{1}}}>=46}}|1|*46{{#ifeq:{{#expr:{{{1}}}>=47}}|1|*47{{#ifeq:{{#expr:{{{1}}}>=48}}|1|*48{{#ifeq:{{#expr:{{{1}}}>=49}}|1|*49{{#ifeq:{{#expr:{{{1}}}>=50}}|1|*50{{#ifeq:{{#expr:{{{1}}}>=51}}|1|*51{{#ifeq:{{#expr:{{{1}}}>=52}}|1|*52{{#ifeq:{{#expr:{{{1}}}>=53}}|1|*53{{#ifeq:{{#expr:{{{1}}}>=54}}|1|*54{{#ifeq:{{#expr:{{{1}}}>=55}}|1|*55{{#ifeq:{{#expr:{{{1}}}>=56}}|1|*56{{#ifeq:{{#expr:{{{1}}}>=57}}|1|*57{{#ifeq:{{#expr:{{{1}}}>=58}}|1|*58{{#ifeq:{{#expr:{{{1}}}>=59}}|1|*59{{#ifeq:{{#expr:{{{1}}}>=60}}|1|*60{{#ifeq:{{#expr:{{{1}}}>=61}}|1|*61{{#ifeq:{{#expr:{{{1}}}>=62}}|1|*62{{#ifeq:{{#expr:{{{1}}}>=63}}|1|*63{{#ifeq:{{#expr:{{{1}}}>=64}}|1|*64{{#ifeq:{{#expr:{{{1}}}>=65}}|1|*65{{#ifeq:{{#expr:{{{1}}}>=66}}|1|*66{{#ifeq:{{#expr:{{{1}}}>=67}}|1|*67{{#ifeq:{{#expr:{{{1}}}>=68}}|1|*68{{#ifeq:{{#expr:{{{1}}}>=69}}|1|*69{{#ifeq:{{#expr:{{{1}}}>=70}}|1|*70{{#ifeq:{{#expr:{{{1}}}>=71}}|1|*71{{#ifeq:{{#expr:{{{1}}}>=72}}|1|*72{{#ifeq:{{#expr:{{{1}}}>=73}}|1|*73{{#ifeq:{{#expr:{{{1}}}>=74}}|1|*74{{#ifeq:{{#expr:{{{1}}}>=75}}|1|*75{{#ifeq:{{#expr:{{{1}}}>=76}}|1|*76{{#ifeq:{{#expr:{{{1}}}>=77}}|1|*77{{#ifeq:{{#expr:{{{1}}}>=78}}|1|*78{{#ifeq:{{#expr:{{{1}}}>=79}}|1|*79{{#ifeq:{{#expr:{{{1}}}>=80}}|1|*80{{#ifeq:{{#expr:{{{1}}}>=81}}|1|*81{{#ifeq:{{#expr:{{{1}}}>=82}}|1|*82{{#ifeq:{{#expr:{{{1}}}>=83}}|1|*83{{#ifeq:{{#expr:{{{1}}}>=84}}|1|*84{{#ifeq:{{#expr:{{{1}}}>=85}}|1|*85{{#ifeq:{{#expr:{{{1}}}>=86}}|1|*86{{#ifeq:{{#expr:{{{1}}}>=87}}|1|*87{{#ifeq:{{#expr:{{{1}}}>=88}}|1|*88{{#ifeq:{{#expr:{{{1}}}>=89}}|1|*89{{#ifeq:{{#expr:{{{1}}}>=90}}|1|*90{{#ifeq:{{#expr:{{{1}}}>=91}}|1|*91{{#ifeq:{{#expr:{{{1}}}>=92}}|1|*92{{#ifeq:{{#expr:{{{1}}}>=93}}|1|*93{{#ifeq:{{#expr:{{{1}}}>=94}}|1|*94{{#ifeq:{{#expr:{{{1}}}>=95}}|1|*95{{#ifeq:{{#expr:{{{1}}}>=96}}|1|*96{{#ifeq:{{#expr:{{{1}}}>=97}}|1|*97{{#ifeq:{{#expr:{{{1}}}>=98}}|1|*98{{#ifeq:{{#expr:{{{1}}}>=99}}|1|*99}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} -{{Template documentation}} -This template finds the [[factorial]] of a number. To use it, enter:
    -{{factorial|input}}
    -The input must be a positive interger smaller than 100 (better than most calculators, which go up to only 69). This template works by repeating conditional multiplications. Examples:
    -*{{factorial|2}} gives {{factorial|2}} -*{{factorial|3}} gives {{factorial|3}} -*{{factorial|5}} gives {{factorial|5}} -*{{factorial|10}} gives {{factorial|10}} -*{{factorial|80}} gives {{factorial|80}} -*{{factorial|0.5}} gives {{factorial|0.5}} (invalid input) -*{{factorial|-1}} gives {{factorial|-1}} (invalid input) -{{esoteric}} -[[Category:Mathematical templates|{{PAGENAME}}]] -
    - diff --git a/tests/parser/preprocess/Fundraising.expected b/tests/parser/preprocess/Fundraising.expected deleted file mode 100644 index f5b32cc5..00000000 --- a/tests/parser/preprocess/Fundraising.expected +++ /dev/null @@ -1,18 +0,0 @@ -<div name="fundraising" id="fundraising" class="plainlinks" style="margin-top:5px; text-align: center; background-color: #ffffe0; border: solid 1px #e0e0c0"> -'''Pwede kang [[Wikimedia:give the gift of knowledge|maghandog ng kaalaman]] sa paraan ng [[Wikimedia:Fundraising#Donation_methods|pagbibigay ng donasyon sa Pundasyong Wikimedia!]]''' -<br /> -<fundraising/> -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -<fundraisinglogo/> -<br /> -<b>Ngayon, ang iyong [[Wikimedia:Fundraising|kontribusyon]] ay [[Wikimedia:Fundraising FAQ|itatambal]] ng isang anonimong kaibigan.</b> -<br /> -<small> -[[Wikimedia:Deductibility of donations|Pagbabawas sa mga buwis ng donasyon]] -| -[[Wikimedia:Fundraising FAQ|FAQ]] -| -[http://upload.wikimedia.org/wikipedia/foundation/2/28/Wikimedia_2006_fs.pdf Mga pampananalaping pahayag] -</small> -</div> - \ No newline at end of file diff --git a/tests/parser/preprocess/Fundraising.txt b/tests/parser/preprocess/Fundraising.txt deleted file mode 100644 index b868b4d8..00000000 --- a/tests/parser/preprocess/Fundraising.txt +++ /dev/null @@ -1,17 +0,0 @@ - diff --git a/tests/parser/preprocess/QuoteQuran.expected b/tests/parser/preprocess/QuoteQuran.expected deleted file mode 100644 index e9a78e46..00000000 --- a/tests/parser/preprocess/QuoteQuran.expected +++ /dev/null @@ -1,140 +0,0 @@ -<noinclude></noinclude> -<div class="boilerplate metadata rfa" style="background-color:#FFFFF5; margin: 2em 0 0 0; padding: 0 10px 0 10px; border: 1px solid #AAAAAA;">The [[Qur'an]], [[sura|chapter]] , [[ayat|verse]] [http://www.usc.edu/dept/MSA/quran/.qmt.html#. 21]''':'''</font></div> - - \ No newline at end of file diff --git a/tests/parser/preprocess/QuoteQuran.txt b/tests/parser/preprocess/QuoteQuran.txt deleted file mode 100644 index 3cfac5b2..00000000 --- a/tests/parser/preprocess/QuoteQuran.txt +++ /dev/null @@ -1,139 +0,0 @@ -{{Template sandbox notice}} -
    - diff --git a/tests/parserTests.php b/tests/parserTests.php deleted file mode 100644 index 4df9a618..00000000 --- a/tests/parserTests.php +++ /dev/null @@ -1,92 +0,0 @@ - - * http://www.mediawiki.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - * @ingroup Testing - */ - -$otions = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled' ); -$optionsWithArgs = array( 'regex', 'filter', 'seed', 'setversion' ); - -require_once( __DIR__ . '/../maintenance/commandLine.inc' ); - -if ( isset( $options['help'] ) ) { - echo << Run test cases from a custom file instead of parserTests.txt - --record Record tests in database - --compare Compare with recorded results, without updating the database. - --setversion When using --record, set the version string to use (useful - with git-svn so that you can get the exact revision) - --keep-uploads Re-use the same upload directory for each test, don't delete it - --fuzz Do a fuzz test instead of a normal test - --seed Start the fuzz test from the specified seed - --help Show this help message - --run-disabled run disabled tests - -ENDS; - exit( 0 ); -} - -# Cases of weird db corruption were encountered when running tests on earlyish -# versions of SQLite -if ( $wgDBtype == 'sqlite' ) { - $db = wfGetDB( DB_MASTER ); - $version = $db->getServerVersion(); - if ( version_compare( $version, '3.6' ) < 0 ) { - die( "Parser tests require SQLite version 3.6 or later, you have $version\n" ); - } -} - -# There is a convention that the parser should never -# refer to $wgTitle directly, but instead use the title -# passed to it. -$wgTitle = Title::newFromText( 'Parser test script do not use' ); -$tester = new ParserTest($options); - -if ( isset( $options['file'] ) ) { - $files = array( $options['file'] ); -} else { - // Default parser tests and any set from extensions or local config - $files = $wgParserTestFiles; -} - -# Print out software version to assist with locating regressions -$version = SpecialVersion::getVersion(); -echo( "This is MediaWiki version {$version}.\n\n" ); - -if ( isset( $options['fuzz'] ) ) { - $tester->fuzzTest( $files ); -} else { - $ok = $tester->runTestsFromFiles( $files ); - exit ( $ok ? 0 : 1 ); -} diff --git a/tests/phpunit/Makefile b/tests/phpunit/Makefile deleted file mode 100644 index 8a55dae0..00000000 --- a/tests/phpunit/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -.PHONY: help test phpunit install coverage warning destructive parser noparser safe databaseless list-groups -.DEFAULT: warning - -SHELL = /bin/sh -CONFIG_FILE = $(shell pwd)/suite.xml -PHP = php -PU = ${PHP} phpunit.php --configuration ${CONFIG_FILE} ${FLAGS} - -all test: warning - -warning: - @echo "Run 'make help' to get usage" - @echo "" - @echo "WARNING -- some tests are DESTRUCTIVE and will alter your wiki." - @echo "DO NOT RUN THESE TESTS on a production wiki." - @echo "" - @echo "Until the default tests are made non-destructive, you can run" - @echo "the destructive tests like so:" - @echo "" - @echo " make destructive" - @echo "" - @echo "Some tests are expected to be safe, you can run them with" - @echo "" - @echo " make safe" - @echo "" - @echo "You are recommended to run the tests with read-only credentials." - @echo "" - @echo "If you don't have a database running, you can still run" - @echo "" - @echo " make databaseless" - @echo "" - -destructive: phpunit - -phpunit: - ${PU} - -install: - ./install-phpunit.sh - -tap: - ${PU} --tap - -coverage: - ${PU} --coverage-html ../../docs/code-coverage - -parser: - ${PU} --group Parser -parserfuzz: - @echo "******************************************************************" - @echo "* This WILL kill your computer by eating all memory AND all swap *" - @echo "* *" - @echo "* If you are on a production machine. ABORT NOW!! *" - @echo "* Press control+C to stop *" - @echo "* *" - @echo "******************************************************************" - ${PU} --group Parser,ParserFuzz -noparser: - ${PU} --exclude-group Parser,Broken,ParserFuzz,Stub - -safe: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub - -databaseless: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Database,Stub - -database: - ${PU} --exclude-group Broken,ParserFuzz,Destructive,Stub --group Database - -list-groups: - ${PU} --list-groups - -help: - # Usage: - # make [OPTION=value] - # - # Targets: - # phpunit (default) Run all the tests with phpunit - # install Install PHPUnit from phpunit.de - # tap Run the tests individually through Test::Harness's prove(1) - # help You're looking at it! - # coverage Run the tests and generates an HTML code coverage report - # You will need the Xdebug PHP extension for the later. - # [no]parser Skip or only run Parser tests - # - # list-groups List availabe Tests groups. - # - # Options: - # CONFIG_FILE Path to a PHPUnit configuration file (default: suite.xml) - # FLAGS Additional flags to pass to PHPUnit - # PHP Path to php diff --git a/tests/phpunit/MediaWikiLangTestCase.php b/tests/phpunit/MediaWikiLangTestCase.php deleted file mode 100644 index 6dd8ea35..00000000 --- a/tests/phpunit/MediaWikiLangTestCase.php +++ /dev/null @@ -1,42 +0,0 @@ -getCode() ) { - throw new MWException("Error in MediaWikiLangTestCase::setUp(): " . - "\$wgLanguageCode ('$wgLanguageCode') is different from " . - "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" ); - } - - $wgLanguageCode = 'en'; # For mainpage to be 'Main Page' - - $wgContLang = $wgLang = Language::factory( $wgLanguageCode ); - MessageCache::singleton()->disable(); - - } - - public function tearDown() { - global $wgContLang, $wgLang, $wgLanguageCode; - $wgLang = self::$oldLang; - - $wgContLang = self::$oldContLang; - $wgLanguageCode = $wgContLang->getCode(); - self::$oldContLang = self::$oldLang = null; - - parent::tearDown(); - } - -} diff --git a/tests/phpunit/MediaWikiPHPUnitCommand.php b/tests/phpunit/MediaWikiPHPUnitCommand.php deleted file mode 100644 index fca32515..00000000 --- a/tests/phpunit/MediaWikiPHPUnitCommand.php +++ /dev/null @@ -1,76 +0,0 @@ - false, - 'file=' => false, - 'use-filebackend=' => false, - 'keep-uploads' => false, - 'use-normal-tables' => false, - 'reuse-db' => false, - ); - - public function __construct() { - foreach( self::$additionalOptions as $option => $default ) { - $this->longOptions[$option] = $option . 'Handler'; - } - - } - - public static function main( $exit = true ) { - $command = new self; - - if( wfIsWindows() ) { - # Windows does not come anymore with ANSI.SYS loaded by default - # PHPUnit uses the suite.xml parameters to enable/disable colors - # which can be then forced to be enabled with --colors. - # The below code inject a parameter just like if the user called - # phpunit with a --no-color option (which does not exist). It - # overrides the suite.xml setting. - # Probably fix bug 29226 - $command->arguments['colors'] = false; - } - - # Makes MediaWiki PHPUnit directory includable so the PHPUnit will - # be able to resolve relative files inclusion such as suites/* - # PHPUnit uses stream_resolve_include_path() internally - # See bug 32022 - set_include_path( - __DIR__ - .PATH_SEPARATOR - . get_include_path() - ); - - $command->run($_SERVER['argv'], $exit); - } - - public function __call( $func, $args ) { - - if( substr( $func, -7 ) == 'Handler' ) { - if( is_null( $args[0] ) ) $args[0] = true; //Booleans - self::$additionalOptions[substr( $func, 0, -7 ) ] = $args[0]; - } - } - - public function showHelp() { - parent::showHelp(); - - print <<backupGlobals = false; - $this->backupStaticAttributes = false; - } - - function run( PHPUnit_Framework_TestResult $result = NULL ) { - /* Some functions require some kind of caching, and will end up using the db, - * which we can't allow, as that would open a new connection for mysql. - * Replace with a HashBag. They would not be going to persist anyway. - */ - ObjectCache::$instances[CACHE_DB] = new HashBagOStuff; - - if( $this->needsDB() ) { - global $wgDBprefix; - - $this->useTemporaryTables = !$this->getCliArg( 'use-normal-tables' ); - $this->reuseDB = $this->getCliArg('reuse-db'); - - $this->db = wfGetDB( DB_MASTER ); - - $this->checkDbIsSupported(); - - $this->oldTablePrefix = $wgDBprefix; - - if( !self::$dbSetup ) { - $this->initDB(); - self::$dbSetup = true; - } - - $this->addCoreDBData(); - $this->addDBData(); - - parent::run( $result ); - - $this->resetDB(); - } else { - parent::run( $result ); - } - } - - /** - * obtains a new temporary file name - * - * The obtained filename is enlisted to be removed upon tearDown - * - * @returns string: absolute name of the temporary file - */ - protected function getNewTempFile() { - $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); - $this->tmpfiles[] = $fname; - return $fname; - } - - /** - * obtains a new temporary directory - * - * The obtained directory is enlisted to be removed (recursively with all its contained - * files) upon tearDown. - * - * @returns string: absolute name of the temporary directory - */ - protected function getNewTempDirectory() { - // Starting of with a temporary /file/. - $fname = $this->getNewTempFile(); - - // Converting the temporary /file/ to a /directory/ - // - // The following is not atomic, but at least we now have a single place, - // where temporary directory creation is bundled and can be improved - unlink( $fname ); - $this->assertTrue( wfMkdirParents( $fname ) ); - return $fname; - } - - protected function tearDown() { - // Cleaning up temporary files - foreach ( $this->tmpfiles as $fname ) { - if ( is_file( $fname ) || ( is_link( $fname ) ) ) { - unlink( $fname ); - } elseif ( is_dir( $fname ) ) { - wfRecursiveRemoveDir( $fname ); - } - } - - // clean up open transactions - if( $this->needsDB() && $this->db ) { - while( $this->db->trxLevel() > 0 ) { - $this->db->rollback(); - } - } - - parent::tearDown(); - } - - function dbPrefix() { - return $this->db->getType() == 'oracle' ? self::ORA_DB_PREFIX : self::DB_PREFIX; - } - - function needsDB() { - # if the test says it uses database tables, it needs the database - if ( $this->tablesUsed ) { - return true; - } - - # if the test says it belongs to the Database group, it needs the database - $rc = new ReflectionClass( $this ); - if ( preg_match( '/@group +Database/im', $rc->getDocComment() ) ) { - return true; - } - - return false; - } - - /** - * Stub. If a test needs to add additional data to the database, it should - * implement this method and do so - */ - function addDBData() {} - - private function addCoreDBData() { - # disabled for performance - #$this->tablesUsed[] = 'page'; - #$this->tablesUsed[] = 'revision'; - - if ( $this->db->getType() == 'oracle' ) { - - # Insert 0 user to prevent FK violations - # Anonymous user - $this->db->insert( 'user', array( - 'user_id' => 0, - 'user_name' => 'Anonymous' ), __METHOD__, array( 'IGNORE' ) ); - - # Insert 0 page to prevent FK violations - # Blank page - $this->db->insert( 'page', array( - 'page_id' => 0, - 'page_namespace' => 0, - 'page_title' => ' ', - 'page_restrictions' => NULL, - 'page_counter' => 0, - 'page_is_redirect' => 0, - 'page_is_new' => 0, - 'page_random' => 0, - 'page_touched' => $this->db->timestamp(), - 'page_latest' => 0, - 'page_len' => 0 ), __METHOD__, array( 'IGNORE' ) ); - - } - - User::resetIdByNameCache(); - - //Make sysop user - $user = User::newFromName( 'UTSysop' ); - - if ( $user->idForName() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTSysopPassword' ); - - $user->addGroup( 'sysop' ); - $user->addGroup( 'bureaucrat' ); - $user->saveSettings(); - } - - - //Make 1 page with 1 revision - $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); - if ( !$page->getId() == 0 ) { - $page->doEdit( 'UTContent', - 'UTPageSummary', - EDIT_NEW, - false, - User::newFromName( 'UTSysop' ) ); - } - } - - private function initDB() { - global $wgDBprefix; - if ( $wgDBprefix === $this->dbPrefix() ) { - throw new MWException( 'Cannot run unit tests, the database prefix is already "unittest_"' ); - } - - $tablesCloned = $this->listTables(); - $dbClone = new CloneDatabase( $this->db, $tablesCloned, $this->dbPrefix() ); - $dbClone->useTemporaryTables( $this->useTemporaryTables ); - - if ( ( $this->db->getType() == 'oracle' || !$this->useTemporaryTables ) && $this->reuseDB ) { - CloneDatabase::changePrefix( $this->dbPrefix() ); - $this->resetDB(); - return; - } else { - $dbClone->cloneTableStructure(); - } - - if ( $this->db->getType() == 'oracle' ) { - $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' ); - } - } - - /** - * Empty all tables so they can be repopulated for tests - */ - private function resetDB() { - if( $this->db ) { - if ( $this->db->getType() == 'oracle' ) { - if ( $this->useTemporaryTables ) { - wfGetLB()->closeAll(); - $this->db = wfGetDB( DB_MASTER ); - } else { - foreach( $this->tablesUsed as $tbl ) { - if( $tbl == 'interwiki') continue; - $this->db->query( 'TRUNCATE TABLE '.$this->db->tableName($tbl), __METHOD__ ); - } - } - } else { - foreach( $this->tablesUsed as $tbl ) { - if( $tbl == 'interwiki' || $tbl == 'user' ) continue; - $this->db->delete( $tbl, '*', __METHOD__ ); - } - } - } - } - - function __call( $func, $args ) { - static $compatibility = array( - 'assertInternalType' => 'assertType', - 'assertNotInternalType' => 'assertNotType', - 'assertInstanceOf' => 'assertType', - 'assertEmpty' => 'assertEmpty2', - ); - - if ( method_exists( $this->suite, $func ) ) { - return call_user_func_array( array( $this->suite, $func ), $args); - } elseif ( isset( $compatibility[$func] ) ) { - return call_user_func_array( array( $this, $compatibility[$func] ), $args); - } else { - throw new MWException( "Called non-existant $func method on " - . get_class( $this ) ); - } - } - - private function assertEmpty2( $value, $msg ) { - return $this->assertTrue( $value == '', $msg ); - } - - static private function unprefixTable( $tableName ) { - global $wgDBprefix; - return substr( $tableName, strlen( $wgDBprefix ) ); - } - - static private function isNotUnittest( $table ) { - return strpos( $table, 'unittest_' ) !== 0; - } - - protected function listTables() { - global $wgDBprefix; - - $tables = $this->db->listTables( $wgDBprefix, __METHOD__ ); - $tables = array_map( array( __CLASS__, 'unprefixTable' ), $tables ); - - // Don't duplicate test tables from the previous fataled run - $tables = array_filter( $tables, array( __CLASS__, 'isNotUnittest' ) ); - - if ( $this->db->getType() == 'sqlite' ) { - $tables = array_flip( $tables ); - // these are subtables of searchindex and don't need to be duped/dropped separately - unset( $tables['searchindex_content'] ); - unset( $tables['searchindex_segdir'] ); - unset( $tables['searchindex_segments'] ); - $tables = array_flip( $tables ); - } - return $tables; - } - - protected function checkDbIsSupported() { - if( !in_array( $this->db->getType(), $this->supportedDBs ) ) { - throw new MWException( $this->db->getType() . " is not currently supported for unit testing." ); - } - } - - public function getCliArg( $offset ) { - - if( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { - return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; - } - - } - - public function setCliArg( $offset, $value ) { - - MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; - - } - - /** - * Don't throw a warning if $function is deprecated and called later - * - * @param $function String - * @return null - */ - function hideDeprecated( $function ) { - wfSuppressWarnings(); - wfDeprecated( $function ); - wfRestoreWarnings(); - } - - /** - * Asserts that the given database query yields the rows given by $expectedRows. - * The expected rows should be given as indexed (not associative) arrays, with - * the values given in the order of the columns in the $fields parameter. - * Note that the rows are sorted by the columns given in $fields. - * - * @since 1.20 - * - * @param $table String|Array the table(s) to query - * @param $fields String|Array the columns to include in the result (and to sort by) - * @param $condition String|Array "where" condition(s) - * @param $expectedRows Array - an array of arrays giving the expected rows. - * - * @throws MWException if this test cases's needsDB() method doesn't return true. - * Test cases can use "@group Database" to enable database test support, - * or list the tables under testing in $this->tablesUsed, or override the - * needsDB() method. - */ - protected function assertSelect( $table, $fields, $condition, Array $expectedRows ) { - if ( !$this->needsDB() ) { - throw new MWException( 'When testing database state, the test cases\'s needDB()' . - ' method should return true. Use @group Database or $this->tablesUsed.'); - } - - $db = wfGetDB( DB_SLAVE ); - - $res = $db->select( $table, $fields, $condition, wfGetCaller(), array( 'ORDER BY' => $fields ) ); - $this->assertNotEmpty( $res, "query failed: " . $db->lastError() ); - - $i = 0; - - foreach ( $expectedRows as $expected ) { - $r = $res->fetchRow(); - self::stripStringKeys( $r ); - - $i += 1; - $this->assertNotEmpty( $r, "row #$i missing" ); - - $this->assertEquals( $expected, $r, "row #$i mismatches" ); - } - - $r = $res->fetchRow(); - self::stripStringKeys( $r ); - - $this->assertFalse( $r, "found extra row (after #$i)" ); - } - - /** - * Utility method taking an array of elements and wrapping - * each element in it's own array. Useful for data providers - * that only return a single argument. - * - * @since 1.20 - * - * @param array $elements - * - * @return array - */ - protected function arrayWrap( array $elements ) { - return array_map( - function( $element ) { - return array( $element ); - }, - $elements - ); - } - - /** - * Assert that two arrays are equal. By default this means that both arrays need to hold - * the same set of values. Using additional arguments, order and associated key can also - * be set as relevant. - * - * @since 1.20 - * - * @param array $expected - * @param array $actual - * @param boolean $ordered If the order of the values should match - * @param boolean $named If the keys should match - */ - protected function assertArrayEquals( array $expected, array $actual, $ordered = false, $named = false ) { - if ( !$ordered ) { - $this->objectAssociativeSort( $expected ); - $this->objectAssociativeSort( $actual ); - } - - if ( !$named ) { - $expected = array_values( $expected ); - $actual = array_values( $actual ); - } - - call_user_func_array( - array( $this, 'assertEquals' ), - array_merge( array( $expected, $actual ), array_slice( func_get_args(), 4 ) ) - ); - } - - /** - * Put each HTML element on its own line and then equals() the results - * - * Use for nicely formatting of PHPUnit diff output when comparing very - * simple HTML - * - * @since 1.20 - * - * @param String $expected HTML on oneline - * @param String $actual HTML on oneline - * @param String $msg Optional message - */ - protected function assertHTMLEquals( $expected, $actual, $msg='' ) { - $expected = str_replace( '>', ">\n", $expected ); - $actual = str_replace( '>', ">\n", $actual ); - - $this->assertEquals( $expected, $actual, $msg ); - } - - /** - * Does an associative sort that works for objects. - * - * @since 1.20 - * - * @param array $array - */ - protected function objectAssociativeSort( array &$array ) { - uasort( - $array, - function( $a, $b ) { - return serialize( $a ) > serialize( $b ) ? 1 : -1; - } - ); - } - - /** - * Utility function for eliminating all string keys from an array. - * Useful to turn a database result row as returned by fetchRow() into - * a pure indexed array. - * - * @since 1.20 - * - * @param $r mixed the array to remove string keys from. - */ - protected static function stripStringKeys( &$r ) { - if ( !is_array( $r ) ) { - return; - } - - foreach ( $r as $k => $v ) { - if ( is_string( $k ) ) { - unset( $r[$k] ); - } - } - } - - /** - * Asserts that the provided variable is of the specified - * internal type or equals the $value argument. This is useful - * for testing return types of functions that return a certain - * type or *value* when not set or on error. - * - * @since 1.20 - * - * @param string $type - * @param mixed $actual - * @param mixed $value - * @param string $message - */ - protected function assertTypeOrValue( $type, $actual, $value = false, $message = '' ) { - if ( $actual === $value ) { - $this->assertTrue( true, $message ); - } - else { - $this->assertType( $type, $actual, $message ); - } - } - - /** - * Asserts the type of the provided value. This can be either - * in internal type such as boolean or integer, or a class or - * interface the value extends or implements. - * - * @since 1.20 - * - * @param string $type - * @param mixed $actual - * @param string $message - */ - protected function assertType( $type, $actual, $message = '' ) { - if ( is_object( $actual ) ) { - $this->assertInstanceOf( $type, $actual, $message ); - } - else { - $this->assertInternalType( $type, $actual, $message ); - } - } - -} diff --git a/tests/phpunit/README b/tests/phpunit/README deleted file mode 100644 index 0a32ba17..00000000 --- a/tests/phpunit/README +++ /dev/null @@ -1,53 +0,0 @@ -== MediaWiki PHPUnit Tests == - -The unit tests for MediaWiki are implemented using the PHPUnit testing -framework and require PHPUnit to run. - - -=== WARNING === - -Some of the unit tests are DESTRUCTIVE and WILL ALTER YOUR WIKI'S CONTENTS. - -DO NOT RUN THESE TESTS ON A PRODUCTION SYSTEM OR ON ANY SYSTEM WHERE YOU NEED -TO RETAIN YOUR DATA. - - -== Installation == - -If PHPUnit is not installed, follow the installation instructions in the -PHPUnit Manual at: - - http://www.phpunit.de/manual/current/en/installation.html - -- or - - -On Unix-like operating systems, run: - - make install - - -== Running tests == - -The tests are run from your operating system's command line. - -Ensure that you are in the tests/phpunit directory of your MediaWiki -installation. - - -On Unix-like operating systems, the tests runs are controlled with a makefile. -Run command: - - make help - -for a full list of options for running tests. - - -On Windows-family operating systems, run the 'run-tests.bat' batch file. - - -=== Writing tests === - -A guide to writing unit tests for MediaWiki can be found at: - - http://mediawiki.org/wiki/Unit_Testing - diff --git a/tests/phpunit/StructureTest.php b/tests/phpunit/StructureTest.php deleted file mode 100644 index 17ea06c4..00000000 --- a/tests/phpunit/StructureTest.php +++ /dev/null @@ -1,60 +0,0 @@ -markTestSkipped( 'This test does not work on Windows' ); - } - $rootPath = escapeshellarg( __DIR__ ); - $testClassRegex = implode( '|', array( - 'ApiFormatTestBase', - 'ApiTestCase', - 'MediaWikiLangTestCase', - 'MediaWikiTestCase', - 'PHPUnit_Framework_TestCase', - 'DumpTestCase', - ) ); - $testClassRegex = "^class .* extends ($testClassRegex)"; - $finder = "find $rootPath -name '*.php' '!' -name '*Test.php'" . - " | xargs grep -El '$testClassRegex|function suite\('"; - - $results = null; - $exitCode = null; - exec($finder, $results, $exitCode); - - $this->assertEquals( - 0, - $exitCode, - 'Verify find/grep command succeeds.' - ); - - $results = array_filter( - $results, - array( $this, 'filterSuites' ) - ); - $strip = strlen( $rootPath ) - 1; - foreach( $results as $k => $v) { - $results[$k] = substr( $v, $strip ); - } - $this->assertEquals( - array(), - $results, - "Unit test file in $rootPath must end with Test." - ); - } - - /** - * Filter to remove testUnitTestFileNamesEndWithTest false positives. - */ - public function filterSuites( $filename ) { - return strpos( $filename, __DIR__ . '/suites/' ) !== 0; - } -} diff --git a/tests/phpunit/TODO b/tests/phpunit/TODO deleted file mode 100644 index b2fa7fb6..00000000 --- a/tests/phpunit/TODO +++ /dev/null @@ -1,10 +0,0 @@ -== Things To Do == -* Most of the tests are named poorly; naming should describe a use case in story-like language, not simply identify the -unit under test. An example would be the difference between testCalculate and testAddingIntegersTogetherWorks. -* Many of the tests make multiple assertions, and are thus not unitary tests. By using data-providers and more use-case -oriented test selection nearly all of these cases can be easily resolved. -* Some of the test files are either incorrectly named or in the wrong folder. Tests should be organized in a mirrored -structure to the source they are testing, and named the same, with the exception of the word "Test" at the end. -* Shared set-up code or base classes are present, but usually named improperly or appear to be poorly factored. Support -code should share as much of the same naming as the code it's supporting, and test and test-case depenencies should be -considered to resolve other shared needs. diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php deleted file mode 100644 index 933767e7..00000000 --- a/tests/phpunit/bootstrap.php +++ /dev/null @@ -1,32 +0,0 @@ - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/phpunit/data/media/Png-native-test.png b/tests/phpunit/data/media/Png-native-test.png deleted file mode 100644 index a0b81ca9..00000000 Binary files a/tests/phpunit/data/media/Png-native-test.png and /dev/null differ diff --git a/tests/phpunit/data/media/QA_icon.svg b/tests/phpunit/data/media/QA_icon.svg deleted file mode 100644 index 6b5d86e4..00000000 --- a/tests/phpunit/data/media/QA_icon.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ? - - - - - - - - \ No newline at end of file diff --git a/tests/phpunit/data/media/README b/tests/phpunit/data/media/README deleted file mode 100644 index fe3bc682..00000000 --- a/tests/phpunit/data/media/README +++ /dev/null @@ -1,38 +0,0 @@ -This directory contains media files for use with the -tests in includes/media directory. - -Image credits: - -QA_icon.svg: -http://es.wikipedia.org/wiki/Archivo:QA_icon.svg -GNU Lesser General Public License -~~helix84 (16.4.2007), Philverney (6.12.2005) David Vignoni - -Gtk-media-play-ltr.svg -http://commons.wikimedia.org/wiki/File:Gtk-media-play-ltr.svg -GNU Lesser General Public License -http://ftp.gnome.org/pub/GNOME/sources/gnome-themes-extras/0.9/gnome-themes-extras-0.9.0.tar.gz -David Vignoni - -US_states_by_total_state_tax_revenue.svg -http://commons.wikimedia.org/wiki/File:US_states_by_total_state_tax_revenue.svg -CC-BY 3.0 -TastyCakes on English Wikipedia - -greyscale-na-png.png, rgb-png.png, Xmp-exif-multilingual_test.jpg -greyscale-png.png, 1bit-png.png, Png-native-test.png, rgb-na-png.png, -test.tiff, test.jpg, jpeg-comment-multiple.jpg, jpeg-comment-utf.jpg, -jpeg-comment-iso8859-1.jpg, jpeg-comment-binary.jpg, jpeg-xmp-psir.jpg, -jpeg-xmp-alt.jpg, animated.gif, exif-user-comment.jpg, animated-xmp.gif, -iptc-timetest-invalid.jpg, jpeg-iptc-bad-hash.jpg, iptc-timetest.jpg, -xmp.png, nonanimated.gif, exif-gps.jpg, jpeg-xmp-psir.xmp, jpeg-iptc-good-hash.jpg, -jpeg-padding-even.jpg, jpeg-padding-odd.jpg -Are all by Bawolff. I don't think they contain enough originality to -claim copyright, but on the off chance they do, feel free to use them -however you feel fit, without restriction. - -Animated_PNG_example_bouncing_beach_ball.png -http://commons.wikimedia.org/wiki/File:Animated_PNG_example_bouncing_beach_ball.png (originally http://www.treebuilder.de/default.asp?file=89031.xml ) -Public Domain -Holger Will - diff --git a/tests/phpunit/data/media/Toll_Texas_1.svg b/tests/phpunit/data/media/Toll_Texas_1.svg deleted file mode 100644 index 73004e3e..00000000 --- a/tests/phpunit/data/media/Toll_Texas_1.svg +++ /dev/null @@ -1,150 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg b/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg deleted file mode 100644 index 9afea859..00000000 --- a/tests/phpunit/data/media/US_states_by_total_state_tax_revenue.svg +++ /dev/null @@ -1,248 +0,0 @@ - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/phpunit/data/media/Wikimedia-logo.svg b/tests/phpunit/data/media/Wikimedia-logo.svg deleted file mode 100644 index 1e17acbe..00000000 --- a/tests/phpunit/data/media/Wikimedia-logo.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - \ No newline at end of file diff --git a/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg b/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg deleted file mode 100644 index f7b23025..00000000 Binary files a/tests/phpunit/data/media/Xmp-exif-multilingual_test.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/animated-xmp.gif b/tests/phpunit/data/media/animated-xmp.gif deleted file mode 100644 index fcba079d..00000000 Binary files a/tests/phpunit/data/media/animated-xmp.gif and /dev/null differ diff --git a/tests/phpunit/data/media/animated.gif b/tests/phpunit/data/media/animated.gif deleted file mode 100644 index a8f248b3..00000000 Binary files a/tests/phpunit/data/media/animated.gif and /dev/null differ diff --git a/tests/phpunit/data/media/broken_exif_date.jpg b/tests/phpunit/data/media/broken_exif_date.jpg deleted file mode 100644 index 82f62f57..00000000 Binary files a/tests/phpunit/data/media/broken_exif_date.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/exif-gps.jpg b/tests/phpunit/data/media/exif-gps.jpg deleted file mode 100644 index 40137340..00000000 Binary files a/tests/phpunit/data/media/exif-gps.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/exif-user-comment.jpg b/tests/phpunit/data/media/exif-user-comment.jpg deleted file mode 100644 index 9f23966a..00000000 Binary files a/tests/phpunit/data/media/exif-user-comment.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/greyscale-na-png.png b/tests/phpunit/data/media/greyscale-na-png.png deleted file mode 100644 index 4a4b7452..00000000 Binary files a/tests/phpunit/data/media/greyscale-na-png.png and /dev/null differ diff --git a/tests/phpunit/data/media/greyscale-png.png b/tests/phpunit/data/media/greyscale-png.png deleted file mode 100644 index 340a67b4..00000000 Binary files a/tests/phpunit/data/media/greyscale-png.png and /dev/null differ diff --git a/tests/phpunit/data/media/iptc-invalid-psir.jpg b/tests/phpunit/data/media/iptc-invalid-psir.jpg deleted file mode 100644 index 01b9acf3..00000000 Binary files a/tests/phpunit/data/media/iptc-invalid-psir.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/iptc-timetest-invalid.jpg b/tests/phpunit/data/media/iptc-timetest-invalid.jpg deleted file mode 100644 index b03e192a..00000000 Binary files a/tests/phpunit/data/media/iptc-timetest-invalid.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/iptc-timetest.jpg b/tests/phpunit/data/media/iptc-timetest.jpg deleted file mode 100644 index db9932ba..00000000 Binary files a/tests/phpunit/data/media/iptc-timetest.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-comment-binary.jpg b/tests/phpunit/data/media/jpeg-comment-binary.jpg deleted file mode 100644 index b467fe43..00000000 Binary files a/tests/phpunit/data/media/jpeg-comment-binary.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg b/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg deleted file mode 100644 index d9ffbac1..00000000 Binary files a/tests/phpunit/data/media/jpeg-comment-iso8859-1.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-comment-multiple.jpg b/tests/phpunit/data/media/jpeg-comment-multiple.jpg deleted file mode 100644 index 363c7385..00000000 Binary files a/tests/phpunit/data/media/jpeg-comment-multiple.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-comment-utf.jpg b/tests/phpunit/data/media/jpeg-comment-utf.jpg deleted file mode 100644 index d6d35b4b..00000000 Binary files a/tests/phpunit/data/media/jpeg-comment-utf.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg b/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg deleted file mode 100644 index 6464c5b8..00000000 Binary files a/tests/phpunit/data/media/jpeg-iptc-bad-hash.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg b/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg deleted file mode 100644 index ef970854..00000000 Binary files a/tests/phpunit/data/media/jpeg-iptc-good-hash.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-padding-even.jpg b/tests/phpunit/data/media/jpeg-padding-even.jpg deleted file mode 100644 index c83c66bd..00000000 Binary files a/tests/phpunit/data/media/jpeg-padding-even.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-padding-odd.jpg b/tests/phpunit/data/media/jpeg-padding-odd.jpg deleted file mode 100644 index 25b93308..00000000 Binary files a/tests/phpunit/data/media/jpeg-padding-odd.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-xmp-alt.jpg b/tests/phpunit/data/media/jpeg-xmp-alt.jpg deleted file mode 100644 index 0e2c3f63..00000000 Binary files a/tests/phpunit/data/media/jpeg-xmp-alt.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-xmp-psir.jpg b/tests/phpunit/data/media/jpeg-xmp-psir.jpg deleted file mode 100644 index 4d19fcbe..00000000 Binary files a/tests/phpunit/data/media/jpeg-xmp-psir.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/jpeg-xmp-psir.xmp b/tests/phpunit/data/media/jpeg-xmp-psir.xmp deleted file mode 100644 index fee6ee18..00000000 --- a/tests/phpunit/data/media/jpeg-xmp-psir.xmp +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - jpeg-xmp-psir.jpg - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/phpunit/data/media/landscape-plain.jpg b/tests/phpunit/data/media/landscape-plain.jpg deleted file mode 100644 index cf296555..00000000 Binary files a/tests/phpunit/data/media/landscape-plain.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/nonanimated.gif b/tests/phpunit/data/media/nonanimated.gif deleted file mode 100644 index 9e52a7f0..00000000 Binary files a/tests/phpunit/data/media/nonanimated.gif and /dev/null differ diff --git a/tests/phpunit/data/media/portrait-rotated.jpg b/tests/phpunit/data/media/portrait-rotated.jpg deleted file mode 100644 index 445feaed..00000000 Binary files a/tests/phpunit/data/media/portrait-rotated.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/rgb-na-png.png b/tests/phpunit/data/media/rgb-na-png.png deleted file mode 100644 index 2f2a5ca0..00000000 Binary files a/tests/phpunit/data/media/rgb-na-png.png and /dev/null differ diff --git a/tests/phpunit/data/media/rgb-png.png b/tests/phpunit/data/media/rgb-png.png deleted file mode 100644 index 6f40cc92..00000000 Binary files a/tests/phpunit/data/media/rgb-png.png and /dev/null differ diff --git a/tests/phpunit/data/media/test.jpg b/tests/phpunit/data/media/test.jpg deleted file mode 100644 index cb084253..00000000 Binary files a/tests/phpunit/data/media/test.jpg and /dev/null differ diff --git a/tests/phpunit/data/media/test.tiff b/tests/phpunit/data/media/test.tiff deleted file mode 100644 index 6a36f760..00000000 Binary files a/tests/phpunit/data/media/test.tiff and /dev/null differ diff --git a/tests/phpunit/data/media/xmp.png b/tests/phpunit/data/media/xmp.png deleted file mode 100644 index 6b9f7a87..00000000 Binary files a/tests/phpunit/data/media/xmp.png and /dev/null differ diff --git a/tests/phpunit/data/xmp/1.result.php b/tests/phpunit/data/xmp/1.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/1.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/1.xmp b/tests/phpunit/data/xmp/1.xmp deleted file mode 100644 index 66e15427..00000000 --- a/tests/phpunit/data/xmp/1.xmp +++ /dev/null @@ -1,11 +0,0 @@ - - - - -True 0 1 False False - - diff --git a/tests/phpunit/data/xmp/2.result.php b/tests/phpunit/data/xmp/2.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/2.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/2.xmp b/tests/phpunit/data/xmp/2.xmp deleted file mode 100644 index 0fa6a894..00000000 --- a/tests/phpunit/data/xmp/2.xmp +++ /dev/null @@ -1,12 +0,0 @@ - - - - - -True 1 False False - - diff --git a/tests/phpunit/data/xmp/3-invalid.result.php b/tests/phpunit/data/xmp/3-invalid.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/3-invalid.result.php +++ /dev/null @@ -1,7 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/3-invalid.xmp b/tests/phpunit/data/xmp/3-invalid.xmp deleted file mode 100644 index 2425e254..00000000 --- a/tests/phpunit/data/xmp/3-invalid.xmp +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -0/10 - -fred - - - - - - - - -1 -False - - False False - - diff --git a/tests/phpunit/data/xmp/3.result.php b/tests/phpunit/data/xmp/3.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/3.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/3.xmp b/tests/phpunit/data/xmp/3.xmp deleted file mode 100644 index 2cf19883..00000000 --- a/tests/phpunit/data/xmp/3.xmp +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -0/10 - -fred - - - - - - - -True - -1 -False - - False False - - diff --git a/tests/phpunit/data/xmp/4.result.php b/tests/phpunit/data/xmp/4.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/4.result.php +++ /dev/null @@ -1,7 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/4.xmp b/tests/phpunit/data/xmp/4.xmp deleted file mode 100644 index 29eb614b..00000000 --- a/tests/phpunit/data/xmp/4.xmp +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -0/10 - - -True 0 1 False False - - - - - - diff --git a/tests/phpunit/data/xmp/5.result.php b/tests/phpunit/data/xmp/5.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/5.result.php +++ /dev/null @@ -1,7 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/5.xmp b/tests/phpunit/data/xmp/5.xmp deleted file mode 100644 index 3cc61d68..00000000 --- a/tests/phpunit/data/xmp/5.xmp +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - -True 0 1 False False - - - - - - diff --git a/tests/phpunit/data/xmp/6.result.php b/tests/phpunit/data/xmp/6.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/6.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/6.xmp b/tests/phpunit/data/xmp/6.xmp deleted file mode 100644 index f435ab23..00000000 --- a/tests/phpunit/data/xmp/6.xmp +++ /dev/null @@ -1,18 +0,0 @@ - - - - -0/10 - - - - - -True 0 1 False False - - diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php deleted file mode 100644 index 0efcfa36..00000000 --- a/tests/phpunit/data/xmp/7.result.php +++ /dev/null @@ -1,52 +0,0 @@ - - array ( - 'CameraOwnerName' => 'Me!', - ), - 'xmp-general' => - array ( - 'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9', - 'ImageDescription' => - array ( - 'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp', - '_type' => 'lang', - ), - 'ObjectName' => - array ( - 'x-default' => 'xmp core/xmp rights/cc ns test', - '_type' => 'lang', - ), - 'DateTimeDigitized' => '2005:04:03', - 'Software' => 'The one true editor: Vi (ok i used gimp)', - 'Identifier' => - array ( - 0 => 'http://example.com/identifierurl', - 1 => 'urn:sha1:342524abcdef', - '_type' => 'ul', - ), - 'Label' => 'Test image', - 'DateTimeMetadata' => '2011:05:12', - 'DateTime' => '2007:03:04 06:34:10', - 'Nickname' => 'My little xmp test image', - 'Rating' => '5', - 'RightsCertificate' => 'http://example.com/rights-certificate/', - 'Copyrighted' => 'True', - 'CopyrightOwner' => - array ( - 0 => 'Bawolff is copyright owner', - '_type' => 'ul', - ), - 'UsageTerms' => - array ( - 'x-default' => 'do whatever you want', - 'en-gb' => 'Do whatever you want in british english', - '_type' => 'lang', - ), - 'WebStatement' => 'http://example.com/web_statement', - ), - 'xmp-deprecated' => - array ( - 'Identifier' => 'http://example.com/identifierurl/wrong', - ), -); diff --git a/tests/phpunit/data/xmp/7.xmp b/tests/phpunit/data/xmp/7.xmp deleted file mode 100644 index e18e13d9..00000000 --- a/tests/phpunit/data/xmp/7.xmp +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - Me! - - - - http://creativecommons.com/cc-by-2.9 - - - - - - Test image for the cc: xmp: xmpRights: namespaces in xmp - - - http://example.com/identifierurl/wrong - - - xmp core/xmp rights/cc ns test - - - - - - 2005-04-03 - The one true editor: Vi (ok i used gimp) - - - http://example.com/identifierurl - - urn:sha1:342524abcdef - - - Test image - 2011-05-12 - 2007-03-04T12:34:10-06:00 - My little xmp test image - 7 - - - - http://example.com/rights-certificate/ - True - - - Bawolff is copyright owner - - - - - do whatever you want - Do whatever you want in british english - - - http://example.com/web_statement - - - - diff --git a/tests/phpunit/data/xmp/README b/tests/phpunit/data/xmp/README deleted file mode 100644 index bd949176..00000000 --- a/tests/phpunit/data/xmp/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains a bunch of XMP files -as well as a bunch of php files containing what the -parsed version of the XMP looks like. diff --git a/tests/phpunit/data/xmp/bag-for-seq.result.php b/tests/phpunit/data/xmp/bag-for-seq.result.php deleted file mode 100644 index b5244f88..00000000 --- a/tests/phpunit/data/xmp/bag-for-seq.result.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - 'Artist' => array( - '_type' => 'ul', - 0 => 'The author', - ) - ) -); diff --git a/tests/phpunit/data/xmp/bag-for-seq.xmp b/tests/phpunit/data/xmp/bag-for-seq.xmp deleted file mode 100644 index c6ed5b7c..00000000 --- a/tests/phpunit/data/xmp/bag-for-seq.xmp +++ /dev/null @@ -1 +0,0 @@ - The author diff --git a/tests/phpunit/data/xmp/flash.result.php b/tests/phpunit/data/xmp/flash.result.php deleted file mode 100644 index 018c0ac1..00000000 --- a/tests/phpunit/data/xmp/flash.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '127' - ) -); diff --git a/tests/phpunit/data/xmp/flash.xmp b/tests/phpunit/data/xmp/flash.xmp deleted file mode 100644 index b1373cc2..00000000 --- a/tests/phpunit/data/xmp/flash.xmp +++ /dev/null @@ -1,11 +0,0 @@ - - - - -True 3 3 True True - - diff --git a/tests/phpunit/data/xmp/gps.result.php b/tests/phpunit/data/xmp/gps.result.php deleted file mode 100644 index 2d1243d5..00000000 --- a/tests/phpunit/data/xmp/gps.result.php +++ /dev/null @@ -1,12 +0,0 @@ - - array( - 'GPSAltitude' => -3.14159265301, - 'GPSDOP' => '5/1', - 'GPSLatitude' => 88.51805555, - 'GPSLongitude' => -21.12356945, - 'GPSVersionID' => '2.2.0.0' - ) -); - diff --git a/tests/phpunit/data/xmp/gps.xmp b/tests/phpunit/data/xmp/gps.xmp deleted file mode 100644 index e52d2c8a..00000000 --- a/tests/phpunit/data/xmp/gps.xmp +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - 103993/33102 - 1 - 5/1 - 88,31.083333N - 21,7.414167W - 2.2.0.0 - - - - - diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.result.php b/tests/phpunit/data/xmp/invalid-child-not-struct.result.php deleted file mode 100644 index 5741b2c9..00000000 --- a/tests/phpunit/data/xmp/invalid-child-not-struct.result.php +++ /dev/null @@ -1,7 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ) -); diff --git a/tests/phpunit/data/xmp/invalid-child-not-struct.xmp b/tests/phpunit/data/xmp/invalid-child-not-struct.xmp deleted file mode 100644 index 6aa0c10b..00000000 --- a/tests/phpunit/data/xmp/invalid-child-not-struct.xmp +++ /dev/null @@ -1,12 +0,0 @@ - - - -True 0 1 False False - - - - diff --git a/tests/phpunit/data/xmp/no-namespace.result.php b/tests/phpunit/data/xmp/no-namespace.result.php deleted file mode 100644 index 3ff69201..00000000 --- a/tests/phpunit/data/xmp/no-namespace.result.php +++ /dev/null @@ -1,7 +0,0 @@ - - array( - 'FNumber' => '28/10', - ) -); diff --git a/tests/phpunit/data/xmp/no-namespace.xmp b/tests/phpunit/data/xmp/no-namespace.xmp deleted file mode 100644 index 7d6cdb2f..00000000 --- a/tests/phpunit/data/xmp/no-namespace.xmp +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/tests/phpunit/data/xmp/no-recognized-props.result.php b/tests/phpunit/data/xmp/no-recognized-props.result.php deleted file mode 100644 index b3ca9f5a..00000000 --- a/tests/phpunit/data/xmp/no-recognized-props.result.php +++ /dev/null @@ -1,2 +0,0 @@ - - - - - diff --git a/tests/phpunit/data/xmp/utf16BE.result.php b/tests/phpunit/data/xmp/utf16BE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf16BE.result.php +++ /dev/null @@ -1,12 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '􊯍' - ), -); diff --git a/tests/phpunit/data/xmp/utf16BE.xmp b/tests/phpunit/data/xmp/utf16BE.xmp deleted file mode 100644 index 0cf60d60..00000000 Binary files a/tests/phpunit/data/xmp/utf16BE.xmp and /dev/null differ diff --git a/tests/phpunit/data/xmp/utf16LE.result.php b/tests/phpunit/data/xmp/utf16LE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf16LE.result.php +++ /dev/null @@ -1,12 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '􊯍' - ), -); diff --git a/tests/phpunit/data/xmp/utf16LE.xmp b/tests/phpunit/data/xmp/utf16LE.xmp deleted file mode 100644 index 66d71f4c..00000000 Binary files a/tests/phpunit/data/xmp/utf16LE.xmp and /dev/null differ diff --git a/tests/phpunit/data/xmp/utf32BE.result.php b/tests/phpunit/data/xmp/utf32BE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf32BE.result.php +++ /dev/null @@ -1,12 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '􊯍' - ), -); diff --git a/tests/phpunit/data/xmp/utf32BE.xmp b/tests/phpunit/data/xmp/utf32BE.xmp deleted file mode 100644 index 06afdf92..00000000 Binary files a/tests/phpunit/data/xmp/utf32BE.xmp and /dev/null differ diff --git a/tests/phpunit/data/xmp/utf32LE.result.php b/tests/phpunit/data/xmp/utf32LE.result.php deleted file mode 100644 index ac7ea506..00000000 --- a/tests/phpunit/data/xmp/utf32LE.result.php +++ /dev/null @@ -1,12 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - ), - 'xmp-general' => - array( - 'Label' => '􊯍' - ), -); diff --git a/tests/phpunit/data/xmp/utf32LE.xmp b/tests/phpunit/data/xmp/utf32LE.xmp deleted file mode 100644 index bf2097fe..00000000 Binary files a/tests/phpunit/data/xmp/utf32LE.xmp and /dev/null differ diff --git a/tests/phpunit/data/xmp/xmpExt.result.php b/tests/phpunit/data/xmp/xmpExt.result.php deleted file mode 100644 index beead1bd..00000000 --- a/tests/phpunit/data/xmp/xmpExt.result.php +++ /dev/null @@ -1,8 +0,0 @@ - - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => '9' - ) -); diff --git a/tests/phpunit/data/xmp/xmpExt.xmp b/tests/phpunit/data/xmp/xmpExt.xmp deleted file mode 100644 index da0383f8..00000000 --- a/tests/phpunit/data/xmp/xmpExt.xmp +++ /dev/null @@ -1,13 +0,0 @@ - - - - -True 0 1 False False - - diff --git a/tests/phpunit/data/xmp/xmpExt2.xmp b/tests/phpunit/data/xmp/xmpExt2.xmp deleted file mode 100644 index 060abb2c..00000000 --- a/tests/phpunit/data/xmp/xmpExt2.xmp +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/tests/phpunit/data/zip/cd-gap.zip b/tests/phpunit/data/zip/cd-gap.zip deleted file mode 100644 index b5ae6ccd..00000000 Binary files a/tests/phpunit/data/zip/cd-gap.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/cd-truncated.zip b/tests/phpunit/data/zip/cd-truncated.zip deleted file mode 100644 index 4d40d7d4..00000000 Binary files a/tests/phpunit/data/zip/cd-truncated.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/class-trailing-null.zip b/tests/phpunit/data/zip/class-trailing-null.zip deleted file mode 100644 index 31dcf3d8..00000000 Binary files a/tests/phpunit/data/zip/class-trailing-null.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/class-trailing-slash.zip b/tests/phpunit/data/zip/class-trailing-slash.zip deleted file mode 100644 index 9eb1f037..00000000 Binary files a/tests/phpunit/data/zip/class-trailing-slash.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/class.zip b/tests/phpunit/data/zip/class.zip deleted file mode 100644 index 98a625b7..00000000 Binary files a/tests/phpunit/data/zip/class.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/empty.zip b/tests/phpunit/data/zip/empty.zip deleted file mode 100644 index 15cb0ecb..00000000 Binary files a/tests/phpunit/data/zip/empty.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/looks-like-zip64.zip b/tests/phpunit/data/zip/looks-like-zip64.zip deleted file mode 100644 index 7428cddd..00000000 Binary files a/tests/phpunit/data/zip/looks-like-zip64.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/nosig.zip b/tests/phpunit/data/zip/nosig.zip deleted file mode 100644 index a22c73a4..00000000 Binary files a/tests/phpunit/data/zip/nosig.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/split.zip b/tests/phpunit/data/zip/split.zip deleted file mode 100644 index 6984ae6d..00000000 Binary files a/tests/phpunit/data/zip/split.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/trail.zip b/tests/phpunit/data/zip/trail.zip deleted file mode 100644 index 50bcea12..00000000 Binary files a/tests/phpunit/data/zip/trail.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/wrong-cd-start-disk.zip b/tests/phpunit/data/zip/wrong-cd-start-disk.zip deleted file mode 100644 index 59b45938..00000000 Binary files a/tests/phpunit/data/zip/wrong-cd-start-disk.zip and /dev/null differ diff --git a/tests/phpunit/data/zip/wrong-central-entry-sig.zip b/tests/phpunit/data/zip/wrong-central-entry-sig.zip deleted file mode 100644 index 05329b43..00000000 Binary files a/tests/phpunit/data/zip/wrong-central-entry-sig.zip and /dev/null differ diff --git a/tests/phpunit/docs/ExportDemoTest.php b/tests/phpunit/docs/ExportDemoTest.php deleted file mode 100644 index ce65d494..00000000 --- a/tests/phpunit/docs/ExportDemoTest.php +++ /dev/null @@ -1,36 +0,0 @@ -validateXmlFileAgainstXsd( "../../docs/export-demo.xml" ); - } - - /** - * Validates a xml file against the xsd. - * - * The validation is slow, because php has to read the xsd on each call. - * - * @param $fname string: name of file to validate - */ - protected function validateXmlFileAgainstXsd( $fname ) { - $version = WikiExporter::schemaVersion(); - - $dom = new DomDocument(); - $dom->load( $fname ); - - try { - $this->assertTrue( $dom->schemaValidate( "../../docs/export-" . $version . ".xsd" ), - "schemaValidate has found an error" ); - } catch( Exception $e ) { - $this->fail( "xml not valid against xsd: " . $e->getMessage() ); - } - } -} diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php deleted file mode 100644 index 17cee6e8..00000000 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ /dev/null @@ -1,33 +0,0 @@ -mRights = array( 'createpage', 'edit', 'purge' ); - $wgLanguageCode = 'es'; - $wgContLang = Language::factory( 'es' ); - - $wgLang = Language::factory( 'fr' ); - $status = $page->doEdit( '{{:{{int:history}}}}', 'Test code for bug 14404', 0, false, $user ); - $templates1 = $title->getTemplateLinksFrom(); - - $wgLang = Language::factory( 'de' ); - $page->mPreparedEdit = false; // In order to force the rerendering of the same wikitext - - // We need an edit, a purge is not enough to regenerate the tables - $status = $page->doEdit( '{{:{{int:history}}}}', 'Test code for bug 14404', EDIT_UPDATE, false, $user ); - $templates2 = $title->getTemplateLinksFrom(); - - $this->assertEquals( $templates1, $templates2 ); - $this->assertEquals( $templates1[0]->getFullText(), 'Historial' ); - } - -} diff --git a/tests/phpunit/includes/ArticleTest.php b/tests/phpunit/includes/ArticleTest.php deleted file mode 100644 index 846d2b86..00000000 --- a/tests/phpunit/includes/ArticleTest.php +++ /dev/null @@ -1,82 +0,0 @@ -title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $this->article = new Article( $this->title ); - - } - - /** cleanup title object and its article object */ - function tearDown() { - $this->title = null; - $this->article = null; - - } - - function testImplementsGetMagic() { - $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); - } - - /** - * @depends testImplementsGetMagic - */ - function testImplementsSetMagic() { - $this->article->mLatest = 2; - $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); - } - - /** - * @depends testImplementsSetMagic - */ - function testImplementsCallMagic() { - $this->article->mLatest = 33; - $this->article->mDataLoaded = true; - $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); - } - - function testGetOrSetOnNewProperty() { - $this->article->ext_someNewProperty = 12; - $this->assertEquals( 12, $this->article->ext_someNewProperty, - "Article get/set magic on new field" ); - - $this->article->ext_someNewProperty = -8; - $this->assertEquals( -8, $this->article->ext_someNewProperty, - "Article get/set magic on update to new field" ); - } - - /** - * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) - */ - function testStaticFunctions() { - $this->assertEquals( WikiPage::selectFields(), Article::selectFields(), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleCreate" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "Article::onArticleDelete" ), - "Article static functions" ); - $this->assertEquals( true, is_callable( "ImagePage::onArticleEdit" ), - "Article static functions" ); - $this->assertTrue( is_string( CategoryPage::getAutosummary( '', '', 0 ) ), - "Article static functions" ); - } - - function testWikiPageFactory() { - $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiFilePage', get_class( $page ) ); - - $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiCategoryPage', get_class( $page ) ); - - $title = Title::makeTitle( NS_MAIN, 'SomePage' ); - $page = WikiPage::factory( $title ); - $this->assertEquals( 'WikiPage', get_class( $page ) ); - } -} diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php deleted file mode 100644 index 0c95b8d1..00000000 --- a/tests/phpunit/includes/BlockTest.php +++ /dev/null @@ -1,230 +0,0 @@ -dumpBlocks(); - - $user = User::newFromName( 'UTBlockee' ); - if( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTBlockeePassword' ); - - $user->saveSettings(); - } - - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UTBlockee' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - $this->block = new Block( 'UTBlockee', $user->getID(), 0, - 'Parce que', 0, false, time() + 100500 - ); - $this->madeAt = wfTimestamp( TS_MW ); - - $this->block->insert(); - // save up ID for use in assertion. Since ID is an autoincrement, - // its value might change depending on the order the tests are run. - // ApiBlockTest insert its own blocks! - $newBlockId = $this->block->getId(); - if ($newBlockId) { - $this->blockId = $newBlockId; - } else { - throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" ); - } - } - - /** - * debug function : dump the ipblocks table - */ - function dumpBlocks() { - $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' ); - print "Got " . $v->numRows() . " rows. Full dump follow:\n"; - foreach( $v as $row ) { - print_r( $row ); - } - } - - function testInitializerFunctionsReturnCorrectBlock() { - // $this->dumpBlocks(); - - $this->assertTrue( $this->block->equals( Block::newFromTarget('UTBlockee') ), "newFromTarget() returns the same block as the one that was made"); - - $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made"); - - } - - /** - * per bug 26425 - */ - function testBug26425BlockTimestampDefaultsToTime() { - // delta to stop one-off errors when things happen to go over a second mark. - $delta = abs( $this->madeAt - $this->block->mTimestamp ); - $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()"); - - } - - /** - * This is the method previously used to load block info in CheckUser etc - * passing an empty value (empty string, null, etc) as the ip parameter bypasses IP lookup checks. - * - * This stopped working with r84475 and friends: regression being fixed for bug 29116. - * - * @dataProvider dataBug29116 - */ - function testBug29116LoadWithEmptyIp( $vagueTarget ) { - $this->hideDeprecated( 'Block::load' ); - - $uid = User::idFromName( 'UTBlockee' ); - $this->assertTrue( ($uid > 0), 'Must be able to look up the target user during tests' ); - - $block = new Block(); - $ok = $block->load( $vagueTarget, $uid ); - $this->assertTrue( $ok, "Block->load() with empty IP and user ID '$uid' should return a block" ); - - $this->assertTrue( $this->block->equals( $block ), "Block->load() returns the same block as the one that was made when given empty ip param " . var_export( $vagueTarget, true ) ); - } - - /** - * CheckUser since being changed to use Block::newFromTarget started failing - * because the new function didn't accept empty strings like Block::load() - * had. Regression bug 29116. - * - * @dataProvider dataBug29116 - */ - function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { - $block = Block::newFromTarget('UTBlockee', $vagueTarget); - $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) ); - } - - function dataBug29116() { - return array( - array( null ), - array( '' ), - array( false ) - ); - } - - function testBlockedUserCanNotCreateAccount() { - $username = 'BlockedUserToCreateAccountWith'; - $u = User::newFromName( $username ); - $u->setPassword( 'NotRandomPass' ); - $u->addToDatabase(); - unset( $u ); - - - // Sanity check - $this->assertNull( - Block::newFromTarget( $username ), - "$username should not be blocked" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertFalse( - $u->isBlockedFromCreateAccount(), - "Our sandbox user should be able to create account before being blocked" - ); - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ $username, - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - $block->insert(); - - // Reload block from DB - $userBlock = Block::newFromTarget( $username ); - $this->assertTrue( - (bool) $block->prevents( 'createaccount' ), - "Block object in DB should prevents 'createaccount'" - ); - - $this->assertInstanceOf( - 'Block', - $userBlock, - "'$username' block block object should be existent" - ); - - // Reload user - $u = User::newFromName( $username ); - $this->assertTrue( - (bool) $u->isBlockedFromCreateAccount(), - "Our sandbox user '$username' should NOT be able to create account" - ); - } - - function testCrappyCrossWikiBlocks() { - // Delete the last round's block if it's still there - $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); - if ( $oldBlock ) { - // An old block will prevent our new one from saving. - $oldBlock->delete(); - } - - // Foreign perspective (blockee not on current wiki)... - $block = new Block( - /* $address */ 'UserOnForeignWiki', - /* $user */ 14146, - /* $by */ 0, - /* $reason */ 'crosswiki block...', - /* $timestamp */ wfTimestampNow(), - /* $auto */ false, - /* $expiry */ $this->db->getInfinity(), - /* anonOnly */ false, - /* $createAccount */ true, - /* $enableAutoblock */ true, - /* $hideName (ipb_deleted) */ true, - /* $blockEmail */ true, - /* $allowUsertalk */ false, - /* $byName */ 'MetaWikiUser' - ); - - $res = $block->insert( $this->db ); - $this->assertTrue( (bool)$res['id'], 'Block succeeded' ); - - // Local perspective (blockee on current wiki)... - $user = User::newFromName( 'UserOnForeignWiki' ); - $user->addToDatabase(); - // Set user ID to match the test value - $this->db->update( 'user', array( 'user_id' => 14146 ), array( 'user_id' => $user->getId() ) ); - $user = null; // clear - - $block = Block::newFromID( $res['id'] ); - $this->assertEquals( 'UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name' ); - $this->assertEquals( '14146', $block->getTarget()->getId(), 'Correct blockee id' ); - $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' ); - $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' ); - $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' ); - } -} diff --git a/tests/phpunit/includes/CdbTest.php b/tests/phpunit/includes/CdbTest.php deleted file mode 100644 index b5418dd7..00000000 --- a/tests/phpunit/includes/CdbTest.php +++ /dev/null @@ -1,84 +0,0 @@ -markTestSkipped( 'Native CDB support is not available' ); - } - } - - public function testCdb() { - $dir = wfTempDir(); - if ( !is_writable( $dir ) ) { - $this->markTestSkipped( "Temp dir isn't writable" ); - } - - $w1 = new CdbWriter_PHP( "$dir/php.cdb" ); - $w2 = new CdbWriter_DBA( "$dir/dba.cdb" ); - - $data = array(); - for ( $i = 0; $i < 1000; $i++ ) { - $key = $this->randomString(); - $value = $this->randomString(); - $w1->set( $key, $value ); - $w2->set( $key, $value ); - - if ( !isset( $data[$key] ) ) { - $data[$key] = $value; - } - } - - $w1->close(); - $w2->close(); - - $this->assertEquals( - md5_file( "$dir/dba.cdb" ), - md5_file( "$dir/php.cdb" ), - 'same hash' - ); - - $r1 = new CdbReader_PHP( "$dir/php.cdb" ); - $r2 = new CdbReader_DBA( "$dir/dba.cdb" ); - - foreach ( $data as $key => $value ) { - if ( $key === '' ) { - // Known bug - continue; - } - $v1 = $r1->get( $key ); - $v2 = $r2->get( $key ); - - $v1 = $v1 === false ? '(not found)' : $v1; - $v2 = $v2 === false ? '(not found)' : $v2; - - # cdbAssert( 'Mismatch', $key, $v1, $v2 ); - $this->cdbAssert( "PHP error", $key, $v1, $value ); - $this->cdbAssert( "DBA error", $key, $v2, $value ); - } - - unlink( "$dir/dba.cdb" ); - unlink( "$dir/php.cdb" ); - } - - private function randomString() { - $len = mt_rand( 0, 10 ); - $s = ''; - for ( $j = 0; $j < $len; $j++ ) { - $s .= chr( mt_rand( 0, 255 ) ); - } - return $s; - } - - private function cdbAssert( $msg, $key, $v1, $v2 ) { - $this->assertEquals( - $v2, - $v1, - $msg . ', k=' . bin2hex( $key ) - ); - } -} diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php deleted file mode 100644 index cdb6ed2f..00000000 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ /dev/null @@ -1,40 +0,0 @@ -markTestSkipped( 'The xdiff extension is not available' ); - return; - } - if ( !function_exists( 'xdiff_string_rabdiff' ) ) { - $this->markTestSkipped( 'The version of xdiff extension is lower than 1.5.0' ); - return; - } - if ( !extension_loaded( 'hash' ) && !extension_loaded( 'mhash' ) ) { - $this->markTestSkipped( 'Neither the hash nor mhash extension is available' ); - return; - } - } - - /** - * Test for DiffHistoryBlob::xdiffAdler32() - * @dataProvider provideXdiffAdler32 - */ - function testXdiffAdler32( $input ) { - $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); - $dhb = new DiffHistoryBlob; - $myHash = $dhb->xdiffAdler32( $input ); - $this->assertSame( bin2hex( $xdiffHash ), bin2hex( $myHash ), - "Hash of " . addcslashes( $input, "\0..\37!@\@\177..\377" ) ); - } - - function provideXdiffAdler32() { - return array( - array( '', 'Empty string' ), - array( "\0", 'Null' ), - array( "\0\0\0", "Several nulls" ), - array( "Hello", "An ASCII string" ), - array( str_repeat( "x", 6000 ), "A string larger than xdiff's NMAX (5552)" ) - ); - } -} diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php deleted file mode 100644 index 8ecfd7e5..00000000 --- a/tests/phpunit/includes/EditPageTest.php +++ /dev/null @@ -1,40 +0,0 @@ -assertEquals( $title, $extracted ); - } - - function dataExtractSectionTitle() { - return array( - array( - "== Test ==\n\nJust a test section.", - "Test" - ), - array( - "An initial section, no header.", - false - ), - array( - "An initial section with a fake heder (bug 32617)\n\n== Test == ??\nwtf", - false - ), - array( - "== Section ==\nfollowed by a fake == Non-section == ??\nnoooo", - "Section" - ), - array( - "== Section== \t\r\n followed by whitespace (bug 35051)", - 'Section', - ), - ); - } -} diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php deleted file mode 100644 index 92ec7344..00000000 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ /dev/null @@ -1,32 +0,0 @@ -saved_wgExternalStores = $wgExternalStores ; - } - - function tearDown() { - global $wgExternalStores; - $wgExternalStores = $this->saved_wgExternalStores ; - } - - function testExternalStoreDoesNotFetchIncorrectURL() { - global $wgExternalStores; - $wgExternalStores = true; - - # Assertions for r68900 - $this->assertFalse( - ExternalStore::fetchFromURL( 'http://' ) ); - $this->assertFalse( - ExternalStore::fetchFromURL( 'ftp.wikimedia.org' ) ); - $this->assertFalse( - ExternalStore::fetchFromURL( '/super.txt' ) ); - } -} - diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php deleted file mode 100644 index 903a6d25..00000000 --- a/tests/phpunit/includes/ExtraParserTest.php +++ /dev/null @@ -1,169 +0,0 @@ -options = new ParserOptions; - $this->options->setTemplateCallback( array( __CLASS__, 'statelessFetchTemplate' ) ); - $this->parser = new Parser; - - MagicWord::clearCache(); - } - - // Bug 8689 - Long numeric lines kill the parser - function testBug8689() { - global $wgLang; - global $wgUser; - $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; - - if ( $wgLang === null ) $wgLang = new Language; - - $t = Title::newFromText( 'Unit test' ); - $options = ParserOptions::newFromUser( $wgUser ); - $this->assertEquals( "

    $longLine

    ", - $this->parser->parse( $longLine, $t, $options )->getText() ); - } - - /* Test the parser entry points */ - function testParse() { - $title = Title::newFromText( __FUNCTION__ ); - $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}" , $title, $this->options ); - $this->assertEquals( "

    Test\nContent of Template:Foo\nContent of Template:Bar\n

    ", $parserOutput->getText() ); - } - - function testPreSaveTransform() { - global $wgUser; - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); - } - - function testPreprocess() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}" , $title, $this->options ); - - $this->assertEquals( "Test\nContent of ''Template:Foo''\nContent of ''Template:Bar''", $outputText ); - } - - /** - * cleanSig() makes all templates substs and removes tildes - */ - function testCleanSig() { - global $wgCleanSignatures; - $oldCleanSignature = $wgCleanSignatures; - $wgCleanSignatures = true; - - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $wgCleanSignatures = $oldCleanSignature; - - $this->assertEquals( "{{SUBST:Foo}} ", $outputText ); - } - - /** - * cleanSig() should do nothing if disabled - */ - function testCleanSigDisabled() { - global $wgCleanSignatures; - $oldCleanSignature = $wgCleanSignatures; - $wgCleanSignatures = false; - - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); - - $wgCleanSignatures = $oldCleanSignature; - - $this->assertEquals( "{{Foo}} ~~~~", $outputText ); - } - - /** - * cleanSigInSig() just removes tildes - * @dataProvider provideStringsForCleanSigInSig - */ - function testCleanSigInSig( $in, $out ) { - $this->assertEquals( Parser::cleanSigInSig( $in), $out ); - } - - function provideStringsForCleanSigInSig() { - return array( - array( "{{Foo}} ~~~~", "{{Foo}} " ), - array( "~~~", "" ), - array( "~~~~~", "" ), - ); - } - - function testGetSection() { - $outputText2 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 2 ); - $outputText1 = $this->parser->getSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1 ); - - $this->assertEquals( "=== Heading 2 ===\nSection 2", $outputText2 ); - $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); - } - - function testReplaceSection() { - $outputText = $this->parser->replaceSection( "Section 0\n== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2\n== Heading 3 ==\nSection 3\n", 1, "New section 1" ); - - $this->assertEquals( "Section 0\nNew section 1\n\n== Heading 3 ==\nSection 3", $outputText ); - } - - /** - * Templates and comments are not affected, but noinclude/onlyinclude is. - */ - function testGetPreloadText() { - $title = Title::newFromText( __FUNCTION__ ); - $outputText = $this->parser->getPreloadText( "{{Foo}} censored information ", $title, $this->options ); - - $this->assertEquals( "{{Foo}} information ", $outputText ); - } - - static function statelessFetchTemplate( $title, $parser=false ) { - $text = "Content of ''" . $title->getFullText() . "''"; - $deps = array(); - - return array( - 'text' => $text, - 'finalTitle' => $title, - 'deps' => $deps ); - } - - /** - * @group Database - */ - function testTrackingCategory() { - $title = Title::newFromText( __FUNCTION__ ); - $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); - $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); - $expected = array( $cat->getDBkey() ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]" , $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEquals( $expected, $result ); - } - - /** - * @group Database - */ - function testTrackingCategorySpecial() { - // Special pages shouldn't have tracking cats. - $title = SpecialPage::getTitleFor( 'Contributions' ); - $parserOutput = $this->parser->parse( "[[file:nonexistent]]" , $title, $this->options ); - $result = $parserOutput->getCategoryLinks(); - $this->assertEmpty( $result ); - } - } diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php deleted file mode 100644 index c0420049..00000000 --- a/tests/phpunit/includes/FauxResponseTest.php +++ /dev/null @@ -1,70 +0,0 @@ -response = new FauxResponse; - } - - function testCookie() { - $this->assertEquals( null, $this->response->getcookie( 'key' ), 'Non-existing cookie' ); - $this->response->setcookie( 'key', 'val' ); - $this->assertEquals( 'val', $this->response->getcookie( 'key' ), 'Existing cookie' ); - } - - function testHeader() { - $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); - - $this->response->header( 'Location: http://localhost/' ); - $this->assertEquals( 'http://localhost/', $this->response->getheader( 'Location' ), 'Set header' ); - - $this->response->header( 'Location: http://127.0.0.1/' ); - $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header' ); - - $this->response->header( 'Location: http://127.0.0.2/', false ); - $this->assertEquals( 'http://127.0.0.1/', $this->response->getheader( 'Location' ), 'Same header with override disabled' ); - } - - function testResponseCode() { - $this->response->header( 'HTTP/1.1 200' ); - $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); - - $this->response->header( 'HTTP/1.x 201' ); - $this->assertEquals( 201, $this->response->getStatusCode(), 'Header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.1 202 OK' ); - $this->assertEquals( 202, $this->response->getStatusCode(), 'Normal header' ); - - $this->response->header( 'HTTP/1.x 203 OK' ); - $this->assertEquals( 203, $this->response->getStatusCode(), 'Normal header with no message and protocol 1.x' ); - - $this->response->header( 'HTTP/1.x 204 OK', false, 205 ); - $this->assertEquals( 205, $this->response->getStatusCode(), 'Third parameter overrides the HTTP/... header' ); - - $this->response->header( 'Location: http://localhost/', false, 206 ); - $this->assertEquals( 206, $this->response->getStatusCode(), 'Third parameter with another header' ); - } -} diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php deleted file mode 100644 index d86c95d7..00000000 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ /dev/null @@ -1,85 +0,0 @@ -options; - } -} - -/** - * Test class for FormOptions initialization - * Ensure the FormOptions::add() does what we want it to do. - * - * Generated by PHPUnit on 2011-02-28 at 20:46:27. - * - * Copyright © 2011, Antoine Musso - * - * @author Antoine Musso - */ -class FormOptionsInitializationTest extends MediaWikiTestCase { - /** - * @var FormOptions - */ - protected $object; - - - /** - * A new fresh and empty FormOptions object to test initialization - * with. - */ - protected function setUp() { - $this->object = new FormOptionsExposed(); - - } - - public function testAddStringOption() { - $this->object->add( 'foo', 'string value' ); - $this->assertEquals( - array( - 'foo' => array( - 'default' => 'string value', - 'consumed' => false, - 'type' => FormOptions::STRING, - 'value' => null, - ) - ), - $this->object->getOptions() - ); - } - - public function testAddIntegers() { - $this->object->add( 'one', 1 ); - $this->object->add( 'negone', -1 ); - $this->assertEquals( - array( - 'negone' => array( - 'default' => -1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ), - 'one' => array( - 'default' => 1, - 'value' => null, - 'consumed' => false, - 'type' => FormOptions::INT, - ) - ), - $this->object->getOptions() - ); - } - -} diff --git a/tests/phpunit/includes/FormOptionsTest.php b/tests/phpunit/includes/FormOptionsTest.php deleted file mode 100644 index 749343ec..00000000 --- a/tests/phpunit/includes/FormOptionsTest.php +++ /dev/null @@ -1,90 +0,0 @@ -object = new FormOptions; - $this->object->add( 'string1', 'string one' ); - $this->object->add( 'string2', 'string two' ); - $this->object->add( 'integer', 0 ); - $this->object->add( 'intnull', 0, FormOptions::INTNULL ); - } - - /** Helpers for testGuessType() */ - /* @{ */ - private function assertGuessBoolean( $data ) { - $this->guess( FormOptions::BOOL, $data ); - } - private function assertGuessInt( $data ) { - $this->guess( FormOptions::INT, $data ); - } - private function assertGuessString( $data ) { - $this->guess( FormOptions::STRING, $data ); - } - - /** Generic helper */ - private function guess( $expected, $data ) { - $this->assertEquals( - $expected, - FormOptions::guessType( $data ) - ); - } - /* @} */ - - /** - * Reuse helpers above assertGuessBoolean assertGuessInt assertGuessString - */ - public function testGuessTypeDetection() { - $this->assertGuessBoolean( true ); - $this->assertGuessBoolean( false ); - - $this->assertGuessInt( 0 ); - $this->assertGuessInt( -5 ); - $this->assertGuessInt( 5 ); - $this->assertGuessInt( 0x0F ); - - $this->assertGuessString( 'true' ); - $this->assertGuessString( 'false' ); - $this->assertGuessString( '5' ); - $this->assertGuessString( '0' ); - } - - /** - * @expectedException MWException - */ - public function testGuessTypeOnArrayThrowException() { - $this->object->guessType( array( 'foo' ) ); - } - /** - * @expectedException MWException - */ - public function testGuessTypeOnNullThrowException() { - $this->object->guessType( null ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php deleted file mode 100644 index 9097d301..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ /dev/null @@ -1,598 +0,0 @@ -originals['wgReadOnlyFile'] = $wgReadOnlyFile; - $this->originals['wgUrlProtocols'] = $wgUrlProtocols; - $wgReadOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" ); - $wgUrlProtocols[] = 'file://'; - unlink( $wgReadOnlyFile ); - } - - function tearDown() { - global $wgReadOnlyFile, $wgUrlProtocols; - if ( file_exists( $wgReadOnlyFile ) ) { - unlink( $wgReadOnlyFile ); - } - $wgReadOnlyFile = $this->originals['wgReadOnlyFile']; - $wgUrlProtocols = $this->originals['wgUrlProtocols']; - } - - /** @dataProvider provideForWfArrayDiff2 */ - public function testWfArrayDiff2( $a, $b, $expected ) { - $this->assertEquals( - wfArrayDiff2( $a, $b), $expected - ); - } - - // @todo Provide more tests - public function provideForWfArrayDiff2() { - // $a $b $expected - return array( - array( - array( 'a', 'b'), - array( 'a', 'b'), - array(), - ), - array( - array( array( 'a'), array( 'a', 'b', 'c' )), - array( array( 'a'), array( 'a', 'b' )), - array( 1 => array( 'a', 'b', 'c' ) ), - ), - ); - } - - function testRandom() { - # This could hypothetically fail, but it shouldn't ;) - $this->assertFalse( - wfRandom() == wfRandom() ); - } - - function testUrlencode() { - $this->assertEquals( - "%E7%89%B9%E5%88%A5:Contributions/Foobar", - wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); - } - - function testExpandIRI() { - $this->assertEquals( - "https://te.wikibooks.org/wiki/ఉబుంటు_వాడుకరి_మార్గదర్శని", - wfExpandIRI( "https://te.wikibooks.org/wiki/%E0%B0%89%E0%B0%AC%E0%B1%81%E0%B0%82%E0%B0%9F%E0%B1%81_%E0%B0%B5%E0%B0%BE%E0%B0%A1%E0%B1%81%E0%B0%95%E0%B0%B0%E0%B0%BF_%E0%B0%AE%E0%B0%BE%E0%B0%B0%E0%B1%8D%E0%B0%97%E0%B0%A6%E0%B0%B0%E0%B1%8D%E0%B0%B6%E0%B0%A8%E0%B0%BF" ) ); - } - - function testReadOnlyEmpty() { - global $wgReadOnly; - $wgReadOnly = null; - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - function testReadOnlySet() { - global $wgReadOnly, $wgReadOnlyFile; - - $f = fopen( $wgReadOnlyFile, "wt" ); - fwrite( $f, 'Message' ); - fclose( $f ); - $wgReadOnly = null; # Check on $wgReadOnlyFile - - $this->assertTrue( wfReadOnly() ); - $this->assertTrue( wfReadOnly() ); # Check cached - - unlink( $wgReadOnlyFile ); - $wgReadOnly = null; # Clean cache - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - function testQuotedPrintable() { - $this->assertEquals( - "=?UTF-8?Q?=C4=88u=20legebla=3F?=", - UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); - } - - function testTime() { - $start = wfTime(); - $this->assertInternalType( 'float', $start ); - $end = wfTime(); - $this->assertTrue( $end > $start, "Time is running backwards!" ); - } - - function dataArrayToCGI() { - return array( - array( array(), '' ), // empty - array( array( 'foo' => 'bar' ), 'foo=bar' ), // string test - array( array( 'foo' => '' ), 'foo=' ), // empty string test - array( array( 'foo' => 1 ), 'foo=1' ), // number test - array( array( 'foo' => true ), 'foo=1' ), // true test - array( array( 'foo' => false ), '' ), // false test - array( array( 'foo' => null ), '' ), // null test - array( array( 'foo' => 'A&B=5+6@!"\'' ), 'foo=A%26B%3D5%2B6%40%21%22%27' ), // urlencoding test - array( array( 'foo' => 'bar', 'baz' => 'is', 'asdf' => 'qwerty' ), 'foo=bar&baz=is&asdf=qwerty' ), // multi-item test - array( array( 'foo' => array( 'bar' => 'baz' ) ), 'foo%5Bbar%5D=baz' ), - array( array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ), 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf' ), - array( array( 'foo' => array( 'bar', 'baz' ) ), 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ), 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider dataArrayToCGI - */ - function testArrayToCGI( $array, $result ) { - $this->assertEquals( $result, wfArrayToCGI( $array ) ); - } - - - function testArrayToCGI2() { - $this->assertEquals( - "baz=bar&foo=bar", - wfArrayToCGI( - array( 'baz' => 'bar' ), - array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) ); - } - - function dataCgiToArray() { - return array( - array( '', array() ), // empty - array( 'foo=bar', array( 'foo' => 'bar' ) ), // string - array( 'foo=', array( 'foo' => '' ) ), // empty string - array( 'foo', array( 'foo' => '' ) ), // missing = - array( 'foo=bar&qwerty=asdf', array( 'foo' => 'bar', 'qwerty' => 'asdf' ) ), // multiple value - array( 'foo=A%26B%3D5%2B6%40%21%22%27', array( 'foo' => 'A&B=5+6@!"\'' ) ), // urldecoding test - array( 'foo%5Bbar%5D=baz', array( 'foo' => array( 'bar' => 'baz' ) ) ), - array( 'foo%5Bbar%5D=baz&foo%5Bqwerty%5D=asdf', array( 'foo' => array( 'bar' => 'baz', 'qwerty' => 'asdf' ) ) ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz', array( 'foo' => array( 0 => 'bar', 1 => 'baz' ) ) ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz', array( 'foo' => array( 'bar' => array( 'bar' => 'baz' ) ) ) ), - ); - } - - /** - * @dataProvider dataCgiToArray - */ - function testCgiToArray( $cgi, $result ) { - $this->assertEquals( $result, wfCgiToArray( $cgi ) ); - } - - function dataCgiRoundTrip() { - return array( - array( '' ), - array( 'foo=bar' ), - array( 'foo=' ), - array( 'foo=bar&baz=biz' ), - array( 'foo=A%26B%3D5%2B6%40%21%22%27' ), - array( 'foo%5Bbar%5D=baz' ), - array( 'foo%5B0%5D=bar&foo%5B1%5D=baz' ), - array( 'foo%5Bbar%5D%5Bbar%5D=baz' ), - ); - } - - /** - * @dataProvider dataCgiRoundTrip - */ - function testCgiRoundTrip( $cgi ) { - $this->assertEquals( $cgi, wfArrayToCGI( wfCgiToArray( $cgi ) ) ); - } - - function testMimeTypeMatch() { - $this->assertEquals( - 'text/html', - mimeTypeMatch( 'text/html', - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.3 ) ) ); - $this->assertEquals( - 'text/*', - mimeTypeMatch( 'text/html', - array( 'image/*' => 1.0, - 'text/*' => 0.5 ) ) ); - $this->assertEquals( - '*/*', - mimeTypeMatch( 'text/html', - array( '*/*' => 1.0 ) ) ); - $this->assertNull( - mimeTypeMatch( 'text/html', - array( 'image/png' => 1.0, - 'image/svg+xml' => 0.5 ) ) ); - } - - function testNegotiateType() { - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'text/html' => 1.0 ) ) ); - $this->assertEquals( - 'application/xhtml+xml', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/html' => 1.0, - 'text/plain' => 0.5, - 'text/*' => 0.5, - 'application/xhtml+xml' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/*' => 1.0, - 'image/*' => 0.7, - '*/*' => 0.3 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertNull( - wfNegotiateType( - array( 'text/*' => 1.0 ), - array( 'application/xhtml+xml' => 1.0 ) ) ); - } - - function testFallbackMbstringFunctions() { - - if( !extension_loaded( 'mbstring' ) ) { - $this->markTestSkipped( "The mb_string functions must be installed to test the fallback functions" ); - } - - $sampleUTF = "Östergötland_coat_of_arms.png"; - - - //mb_substr - $substr_params = array( - array( 0, 0 ), - array( 5, -4 ), - array( 33 ), - array( 100, -5 ), - array( -8, 10 ), - array( 1, 1 ), - array( 2, -1 ) - ); - - foreach( $substr_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_substr', $param_set ), - MWFunction::callArray( 'Fallback::mb_substr', $param_set ), - 'Fallback mb_substr with params ' . implode( ', ', $old_param_set ) - ); - } - - - //mb_strlen - $this->assertEquals( - mb_strlen( $sampleUTF ), - Fallback::mb_strlen( $sampleUTF ), - 'Fallback mb_strlen' - ); - - - //mb_str(r?)pos - $strpos_params = array( - //array( 'ter' ), - //array( 'Ö' ), - //array( 'Ö', 3 ), - //array( 'oat_', 100 ), - //array( 'c', -10 ), - //Broken for now - ); - - foreach( $strpos_params as $param_set ) { - $old_param_set = $param_set; - array_unshift( $param_set, $sampleUTF ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strpos', $param_set ), - 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) - ); - - $this->assertEquals( - MWFunction::callArray( 'mb_strrpos', $param_set ), - MWFunction::callArray( 'Fallback::mb_strrpos', $param_set ), - 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) - ); - } - - } - - - function testDebugFunctionTest() { - - global $wgDebugLogFile, $wgDebugTimestamps; - - $old_log_file = $wgDebugLogFile; - $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' ); - # @todo FIXME: This setting should be tested - $wgDebugTimestamps = false; - - - - wfDebug( "This is a normal string" ); - $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); - unlink( $wgDebugLogFile ); - - - wfDebug( "This is nöt an ASCII string" ); - $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) ); - unlink( $wgDebugLogFile ); - - - wfDebug( "\00305This has böth UTF and control chars\003" ); - $this->assertEquals( " 05This has böth UTF and control chars ", file_get_contents( $wgDebugLogFile ) ); - unlink( $wgDebugLogFile ); - - wfDebugMem(); - $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - wfDebugMem(true); - $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); - unlink( $wgDebugLogFile ); - - - - $wgDebugLogFile = $old_log_file; - - } - - function testClientAcceptsGzipTest() { - - $settings = array( - 'gzip' => true, - 'bzip' => false, - '*' => false, - 'compress, gzip' => true, - 'gzip;q=1.0' => true, - 'foozip' => false, - 'foo*zip' => false, - 'gzip;q=abcde' => true, //is this REALLY valid? - 'gzip;q=12345678.9' => true, - ' gzip' => true, - ); - - if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) $old_server_setting = $_SERVER['HTTP_ACCEPT_ENCODING']; - - foreach ( $settings as $encoding => $expect ) { - $_SERVER['HTTP_ACCEPT_ENCODING'] = $encoding; - - $this->assertEquals( $expect, wfClientAcceptsGzip( true ), - "'$encoding' => " . wfBoolToStr( $expect ) ); - } - - if( isset( $old_server_setting ) ) $_SERVER['HTTP_ACCEPT_ENCODING'] = $old_server_setting; - - } - - - - function testSwapVarsTest() { - - - $var1 = 1; - $var2 = 2; - - $this->assertEquals( $var1, 1, 'var1 is set originally' ); - $this->assertEquals( $var2, 2, 'var1 is set originally' ); - - swap( $var1, $var2 ); - - $this->assertEquals( $var1, 2, 'var1 is swapped' ); - $this->assertEquals( $var2, 1, 'var2 is swapped' ); - - } - - - function testWfPercentTest() { - - $pcts = array( - array( 6/7, '0.86%', 2, false ), - array( 3/3, '1%' ), - array( 22/7, '3.14286%', 5 ), - array( 3/6, '0.5%' ), - array( 1/3, '0%', 0 ), - array( 10/3, '0%', -1 ), - array( 3/4/5, '0.1%', 1 ), - array( 6/7*8, '6.8571428571%', 10 ), - ); - - foreach( $pcts as $pct ) { - if( !isset( $pct[2] ) ) $pct[2] = 2; - if( !isset( $pct[3] ) ) $pct[3] = true; - - $this->assertEquals( wfPercent( $pct[0], $pct[2], $pct[3] ), $pct[1], $pct[1] ); - } - - } - - - function testInStringTest() { - - $this->assertTrue( in_string( 'foo', 'foobar' ), 'foo is in foobar' ); - $this->assertFalse( in_string( 'Bar', 'foobar' ), 'Case-sensitive by default' ); - $this->assertTrue( in_string( 'Foo', 'foobar', true ), 'Case-insensitive when asked' ); - - } - - /** - * test @see wfShorthandToInteger() - * @dataProvider provideShorthand - */ - public function testWfShorthandToInteger( $shorthand, $expected ) { - $this->assertEquals( $expected, - wfShorthandToInteger( $shorthand ) - ); - } - - /** array( shorthand, expected integer ) */ - public function provideShorthand() { - return array( - # Null, empty ... - array( '', -1), - array( ' ', -1), - array( null, -1), - - # Failures returns 0 :( - array( 'ABCDEFG', 0 ), - array( 'Ak', 0 ), - - # Int, strings with spaces - array( 1, 1 ), - array( ' 1 ', 1 ), - array( 1023, 1023 ), - array( ' 1023 ', 1023 ), - - # kilo, Mega, Giga - array( '1k', 1024 ), - array( '1K', 1024 ), - array( '1m', 1024 * 1024 ), - array( '1M', 1024 * 1024 ), - array( '1g', 1024 * 1024 * 1024 ), - array( '1G', 1024 * 1024 * 1024 ), - - # Negatives - array( -1, -1 ), - array( -500, -500 ), - array( '-500', -500 ), - array( '-1k', -1024 ), - - # Zeroes - array( '0', 0 ), - array( '0k', 0 ), - array( '0M', 0 ), - array( '0G', 0 ), - array( '-0', 0 ), - array( '-0k', 0 ), - array( '-0M', 0 ), - array( '-0G', 0 ), - ); - } - - /** - * @dataProvider provideMakeUrlIndexes() - */ - function testMakeUrlIndexes( $url, $expected ) { - $index = wfMakeUrlIndexes( $url ); - $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); - } - - function provideMakeUrlIndexes() { - return array( - array( - // just a regular :) - 'https://bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' ) - ), - array( - // mailtos are handled special - // is this really right though? that final . probably belongs earlier? - 'mailto:wiki@wikimedia.org', - array( 'mailto:org.wikimedia@wiki.' ) - ), - - // file URL cases per bug 28627... - array( - // three slashes: local filesystem path Unix-style - 'file:///whatever/you/like.txt', - array( 'file://./whatever/you/like.txt' ) - ), - array( - // three slashes: local filesystem path Windows-style - 'file:///c:/whatever/you/like.txt', - array( 'file://./c:/whatever/you/like.txt' ) - ), - array( - // two slashes: UNC filesystem path Windows-style - 'file://intranet/whatever/you/like.txt', - array( 'file://intranet./whatever/you/like.txt' ) - ), - // Multiple-slash cases that can sorta work on Mozilla - // if you hack it just right are kinda pathological, - // and unreliable cross-platform or on IE which means they're - // unlikely to appear on intranets. - // - // Those will survive the algorithm but with results that - // are less consistent. - - // protocol-relative URL cases per bug 29854... - array( - '//bugzilla.wikimedia.org/show_bug.cgi?id=28627', - array( - 'http://org.wikimedia.bugzilla./show_bug.cgi?id=28627', - 'https://org.wikimedia.bugzilla./show_bug.cgi?id=28627' - ) - ), - ); - } - - /** - * @dataProvider provideWfMatchesDomainList - */ - function testWfMatchesDomainList( $url, $domains, $expected, $description ) { - $actual = wfMatchesDomainList( $url, $domains ); - $this->assertEquals( $expected, $actual, $description ); - } - - function provideWfMatchesDomainList() { - $a = array(); - $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); - foreach ( $protocols as $pDesc => $p ) { - $a = array_merge( $a, array( - array( "$p//www.example.com", array(), false, "No matches for empty domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'www.example.com' ), true, "Exact match in domains array, $pDesc URL" ), - array( "$p//www.example.com", array( 'example.com' ), true, "Match without subdomain in domains array, $pDesc URL" ), - array( "$p//www.example2.com", array( 'www.example.com', 'www.example2.com', 'www.example3.com' ), true, "Exact match with other domains in array, $pDesc URL" ), - array( "$p//www.example2.com", array( 'example.com', 'example2.com', 'example3,com' ), true, "Match without subdomain with other domains in array, $pDesc URL" ), - array( "$p//www.example4.com", array( 'example.com', 'example2.com', 'example3,com' ), false, "Domain not in array, $pDesc URL" ), - - // FIXME: This is a bug in wfMatchesDomainList(). If and when this is fixed, update this test case - array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), true, "Substrings of domains match while they shouldn't, $pDesc URL" ), - ) ); - } - return $a; - } - - /** - * @dataProvider provideWfShellMaintenanceCmdList - */ - function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { - if( wfIsWindows() ) { - // Approximation that's good enough for our purposes just now - $expected = str_replace( "'", '"', $expected ); - } - $actual = wfShellMaintenanceCmd( $script, $parameters, $options ); - $this->assertEquals( $expected, $actual, $description ); - } - - function provideWfShellMaintenanceCmdList() { - global $wgPhpCli; - return array( - array( 'eval.php', array( '--help', '--test' ), array(), - "'$wgPhpCli' 'eval.php' '--help' '--test'", - "Called eval.php --help --test" ), - array( 'eval.php', array( '--help', '--test space' ), array('php' => 'php5'), - "'php5' 'eval.php' '--help' '--test space'", - "Called eval.php --help --test with php option" ), - array( 'eval.php', array( '--help', '--test', 'X' ), array('wrapper' => 'MWScript.php'), - "'$wgPhpCli' 'MWScript.php' 'eval.php' '--help' '--test' 'X'", - "Called eval.php --help --test with wrapper option" ), - array( 'eval.php', array( '--help', '--test', 'y' ), array('php' => 'php5', 'wrapper' => 'MWScript.php'), - "'php5' 'MWScript.php' 'eval.php' '--help' '--test' 'y'", - "Called eval.php --help --test with wrapper and php option" ), - ); - } - /* TODO: many more! */ -} - diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php deleted file mode 100644 index 4879a38d..00000000 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ /dev/null @@ -1,29 +0,0 @@ -assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); - } - - function provideWfIsBadImageList() { - $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; - return array( - array( 'Bad.jpg', false, $blacklist, true, - 'Called on a bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'A page' ), $blacklist, true, - 'Called on a bad image' ), - array( 'NotBad.jpg', false, $blacklist, false, - 'Called on a non-bad image' ), - array( 'Bad.jpg', Title::makeTitle( NS_MAIN, 'Nasty page' ), $blacklist, false, - 'Called on a bad image but is on a whitelisted page' ), - array( 'File:Bad.jpg', false, $blacklist, false, - 'Called on a bad image with File:' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/README b/tests/phpunit/includes/GlobalFunctions/README deleted file mode 100644 index 0042bdac..00000000 --- a/tests/phpunit/includes/GlobalFunctions/README +++ /dev/null @@ -1,2 +0,0 @@ -This directory hold tests for includes/GlobalFunctions.php file -which is a pile of functions. diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php deleted file mode 100644 index be6c99e7..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ /dev/null @@ -1,111 +0,0 @@ -assertEquals( - $output, - wfAssembleUrl( $parts ), - "Testing $partsDump assembles to $output" - ); - } - - /** - * Provider of URL parts for testing wfAssembleUrl() - * - * @return array - */ - public function provideURLParts() { - $schemes = array( - '' => array(), - '//' => array( - 'delimiter' => '//', - ), - 'http://' => array( - 'scheme' => 'http', - 'delimiter' => '://', - ), - ); - - $hosts = array( - '' => array(), - 'example.com' => array( - 'host' => 'example.com', - ), - 'example.com:123' => array( - 'host' => 'example.com', - 'port' => 123, - ), - 'id@example.com' => array( - 'user' => 'id', - 'host' => 'example.com', - ), - 'id@example.com:123' => array( - 'user' => 'id', - 'host' => 'example.com', - 'port' => 123, - ), - 'id:key@example.com' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - ), - 'id:key@example.com:123' => array( - 'user' => 'id', - 'pass' => 'key', - 'host' => 'example.com', - 'port' => 123, - ), - ); - - $cases = array(); - foreach ( $schemes as $scheme => $schemeParts ) { - foreach ( $hosts as $host => $hostParts ) { - foreach ( array( '', '/path' ) as $path ) { - foreach ( array( '', 'query' ) as $query ) { - foreach ( array( '', 'fragment' ) as $fragment ) { - $parts = array_merge( - $schemeParts, - $hostParts - ); - $url = $scheme . - $host . - $path; - - if ( $path ) { - $parts['path'] = $path; - } - if ( $query ) { - $parts['query'] = $query; - $url .= '?' . $query; - } - if( $fragment ) { - $parts['fragment'] = $fragment; - $url .= '#' . $fragment; - } - - - $cases[] = array( - $parts, - $url, - ); - } - } - } - } - } - - $complexURL = 'http://id:key@example.org:321' . - '/over/there?name=ferret&foo=bar#nose'; - $cases[] = array( - wfParseUrl( $complexURL ), - $complexURL, - ); - - return $cases; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php deleted file mode 100644 index f4ec7a5f..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ /dev/null @@ -1,133 +0,0 @@ -assertEquals( $expected, wfBCP47($code), - "Applying BCP47 standard to lower case '$code'" - ); - - $code = strtoupper( $code ); - $this->assertEquals( $expected, wfBCP47($code), - "Applying BCP47 standard to upper case '$code'" - ); - } - - /** - * Array format is ($code, $expected) - */ - function provideLanguageCodes() { - return array( - // Extracted from BCP47 (list not exhaustive) - # 2.1.1 - array( 'en-ca-x-ca' , 'en-CA-x-ca' ), - array( 'sgn-be-fr' , 'sgn-BE-FR' ), - array( 'az-latn-x-latn', 'az-Latn-x-latn' ), - # 2.2 - array( 'sr-Latn-RS', 'sr-Latn-RS' ), - array( 'az-arab-ir', 'az-Arab-IR' ), - - # 2.2.5 - array( 'sl-nedis' , 'sl-nedis' ), - array( 'de-ch-1996', 'de-CH-1996' ), - - # 2.2.6 - array( - 'en-latn-gb-boont-r-extended-sequence-x-private', - 'en-Latn-GB-boont-r-extended-sequence-x-private' - ), - - // Examples from BCP47 Appendix A - # Simple language subtag: - array( 'DE', 'de' ), - array( 'fR', 'fr' ), - array( 'ja', 'ja' ), - - # Language subtag plus script subtag: - array( 'zh-hans', 'zh-Hans'), - array( 'sr-cyrl', 'sr-Cyrl'), - array( 'sr-latn', 'sr-Latn'), - - # Extended language subtags and their primary language subtag - # counterparts: - array( 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ), - array( 'cmn-hans-cn' , 'cmn-Hans-CN' ), - array( 'zh-yue-hk' , 'zh-yue-HK' ), - array( 'yue-hk' , 'yue-HK' ), - - # Language-Script-Region: - array( 'zh-hans-cn', 'zh-Hans-CN' ), - array( 'sr-latn-RS', 'sr-Latn-RS' ), - - # Language-Variant: - array( 'sl-rozaj' , 'sl-rozaj' ), - array( 'sl-rozaj-biske', 'sl-rozaj-biske' ), - array( 'sl-nedis' , 'sl-nedis' ), - - # Language-Region-Variant: - array( 'de-ch-1901' , 'de-CH-1901' ), - array( 'sl-it-nedis' , 'sl-IT-nedis' ), - - # Language-Script-Region-Variant: - array( 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ), - - # Language-Region: - array( 'de-de' , 'de-DE' ), - array( 'en-us' , 'en-US' ), - array( 'es-419', 'es-419'), - - # Private use subtags: - array( 'de-ch-x-phonebk' , 'de-CH-x-phonebk' ), - array( 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ), - /** - * Previous test does not reflect the BCP which states: - * az-Arab-x-AZE-derbend - * AZE being private, it should be lower case, hence the test above - * should probably be: - #array( 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ), - */ - - # Private use registry values: - array( 'x-whatever', 'x-whatever' ), - array( 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ), - array( 'de-qaaa' , 'de-Qaaa' ), - array( 'sr-latn-qm', 'sr-Latn-QM' ), - array( 'sr-qaaa-rs', 'sr-Qaaa-RS' ), - - # Tags that use extensions - array( 'en-us-u-islamcal', 'en-US-u-islamcal' ), - array( 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ), - array( 'en-a-myext-b-another', 'en-a-myext-b-another' ), - - # Invalid: - // de-419-DE - // a-DE - // ar-a-aaa-b-bbb-a-ccc - - /* - // ISO 15924 : - array( 'sr-Cyrl', 'sr-Cyrl' ), - # @todo FIXME: Fix our function? - array( 'SR-lATN', 'sr-Latn' ), - array( 'fr-latn', 'fr-Latn' ), - // Use lowercase for single segment - // ISO 3166-1-alpha-2 code - array( 'US', 'us' ), # USA - array( 'uS', 'us' ), # USA - array( 'Fr', 'fr' ), # France - array( 'va', 'va' ), # Holy See (Vatican City State) - */); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php deleted file mode 100644 index 59954b23..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ /dev/null @@ -1,36 +0,0 @@ -assertEquals( $basename, wfBaseName( $fullpath ), - "wfBaseName('$fullpath') => '$basename'" ); - } - - function providePaths() { - return array( - array( '', '' ), - array( '/', '' ), - array( '\\', '' ), - array( '//', '' ), - array( '\\\\', '' ), - array( 'a', 'a' ), - array( 'aaaa', 'aaaa' ), - array( '/a', 'a' ), - array( '\\a', 'a' ), - array( '/aaaa', 'aaaa' ), - array( '\\aaaa', 'aaaa' ), - array( '/aaaa/', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '\\aaaa\\', 'aaaa' ), - array( '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg', - '93px-Zork_Grand_Inquisitor_box_cover.jpg' ), - array( 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE', 'VIEWER.EXE' ), - array( 'Östergötland_coat_of_arms.png', 'Östergötland_coat_of_arms.png' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php deleted file mode 100644 index 192689f8..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ /dev/null @@ -1,80 +0,0 @@ -assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - - // Restore $wgServer and $wgCanonicalServer - $wgServer = $oldServer; - $wgCanonicalServer = $oldCanServer; - } - - /** - * Provider of URL examples for testing wfExpandUrl() - * - * @return array - */ - public function provideExpandableUrls() { - $modes = array( 'http', 'https' ); - $servers = array( 'http' => 'http://example.com', 'https' => 'https://example.com', 'protocol-relative' => '//example.com' ); - $defaultProtos = array( 'http' => PROTO_HTTP, 'https' => PROTO_HTTPS, 'protocol-relative' => PROTO_RELATIVE, 'current' => PROTO_CURRENT, 'canonical' => PROTO_CANONICAL ); - - $retval = array(); - foreach ( $modes as $mode ) { - $httpsMode = $mode == 'https'; - foreach ( $servers as $serverDesc => $server ) { - foreach ( $modes as $canServerMode ) { - $canServer = "$canServerMode://example2.com"; - foreach ( $defaultProtos as $protoDesc => $defaultProto ) { - $retval[] = array( 'http://example.com', 'http://example.com', $defaultProto, $server, $canServer, $httpsMode, "Testing fully qualified http URLs (no need to expand) (defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" ); - $retval[] = array( 'https://example.com', 'https://example.com', $defaultProto, $server, $canServer, $httpsMode, "Testing fully qualified https URLs (no need to expand) (defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" ); - # Would be nice to support this, see fixme on wfExpandUrl() - $retval[] = array( "wiki/FooBar", 'wiki/FooBar', $defaultProto, $server, $canServer, $httpsMode, "Test non-expandable relative URLs (defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" ); - - // Determine expected protocol - $p = $protoDesc . ':'; // default case - if ( $protoDesc == 'protocol-relative' ) { - $p = ''; - } elseif ( $protoDesc == 'current' ) { - $p = "$mode:"; - } elseif ( $protoDesc == 'canonical' ) { - $p = "$canServerMode:"; - } else { - $p = $protoDesc . ':'; - } - // Determine expected server name - if ( $protoDesc == 'canonical' ) { - $srv = $canServer; - } elseif ( $serverDesc == 'protocol-relative' ) { - $srv = $p . $server; - } else { - $srv = $server; - } - - $retval[] = array( "$p//wikipedia.org", '//wikipedia.org', $defaultProto, $server, $canServer, $httpsMode, "Test protocol-relative URL (defaultProto: $protoDesc, wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" ); - $retval[] = array( "$srv/wiki/FooBar", '/wiki/FooBar', $defaultProto, $server, $canServer, $httpsMode, "Testing expanding URL beginning with / (defaultProto: $protoDesc , wgServer: $server, wgCanonicalServer: $canServer, current request protocol: $mode )" ); - } - } - } - } - return $retval; - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php deleted file mode 100644 index 4c4c4c04..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ /dev/null @@ -1,35 +0,0 @@ -assertEquals( __METHOD__, wfGetCaller( 1 ) ); - } - - function callerOne() { - return wfGetCaller(); - } - - function testOne() { - $this->assertEquals( "wfGetCaller::testOne", self::callerOne() ); - } - - function intermediateFunction( $level = 2, $n = 0 ) { - if ( $n > 0 ) - return self::intermediateFunction( $level, $n - 1 ); - return wfGetCaller( $level ); - } - - function testTwo() { - $this->assertEquals( "wfGetCaller::testTwo", self::intermediateFunction() ); - } - - function testN() { - $this->assertEquals( "wfGetCaller::testN", self::intermediateFunction( 2, 0 ) ); - $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( 1, 0 ) ); - - for ($i=0; $i < 10; $i++) - $this->assertEquals( "wfGetCaller::intermediateFunction", self::intermediateFunction( $i + 1, $i ) ); - } -} - diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php deleted file mode 100644 index 1cf0e0fb..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ /dev/null @@ -1,90 +0,0 @@ -assertEquals( - $outputPath, - wfRemoveDotSegments( $inputPath ), - "Testing $inputPath expands to $outputPath" - ); - } - - /** - * Provider of URL paths for testing wfRemoveDotSegments() - * - * @return array - */ - public function providePaths() { - return array( - array( '/a/b/c/./../../g', '/a/g' ), - array( 'mid/content=5/../6', 'mid/6' ), - array( '/a//../b', '/a/b' ), - array( '/.../a', '/.../a' ), - array( '.../a', '.../a' ), - array( '', '' ), - array( '/', '/' ), - array( '//', '//' ), - array( '.', '' ), - array( '..', '' ), - array( '...', '...' ), - array( '/.', '/' ), - array( '/..', '/' ), - array( './', '' ), - array( '../', '' ), - array( './a', 'a' ), - array( '../a', 'a' ), - array( '../../a', 'a' ), - array( '.././a', 'a' ), - array( './../a', 'a' ), - array( '././a', 'a' ), - array( '../../', '' ), - array( '.././', '' ), - array( './../', '' ), - array( '././', '' ), - array( '../..', '' ), - array( '../.', '' ), - array( './..', '' ), - array( './.', '' ), - array( '/../../a', '/a' ), - array( '/.././a', '/a' ), - array( '/./../a', '/a' ), - array( '/././a', '/a' ), - array( '/../../', '/' ), - array( '/.././', '/' ), - array( '/./../', '/' ), - array( '/././', '/' ), - array( '/../..', '/' ), - array( '/../.', '/' ), - array( '/./..', '/' ), - array( '/./.', '/' ), - array( 'b/../../a', '/a' ), - array( 'b/.././a', '/a' ), - array( 'b/./../a', '/a' ), - array( 'b/././a', 'b/a' ), - array( 'b/../../', '/' ), - array( 'b/.././', '/' ), - array( 'b/./../', '/' ), - array( 'b/././', 'b/' ), - array( 'b/../..', '/' ), - array( 'b/../.', '/' ), - array( 'b/./..', '/' ), - array( 'b/./.', 'b/' ), - array( '/b/../../a', '/a' ), - array( '/b/.././a', '/a' ), - array( '/b/./../a', '/a' ), - array( '/b/././a', '/b/a' ), - array( '/b/../../', '/' ), - array( '/b/.././', '/' ), - array( '/b/./../', '/' ), - array( '/b/././', '/b/' ), - array( '/b/../..', '/' ), - array( '/b/../.', '/' ), - array( '/b/./..', '/' ), - array( '/b/./.', '/b/' ), - ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php deleted file mode 100644 index 1df26d2c..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ /dev/null @@ -1,28 +0,0 @@ -assertEquals( - wfShorthandToInteger( $input ), - $output, - $description - ); - } - - function provideABunchOfShorthands() { - return array( - array( '', -1, 'Empty string' ), - array( ' ', -1, 'String of spaces' ), - array( '1G', 1024 * 1024 * 1024, 'One gig uppercased' ), - array( '1g', 1024 * 1024 * 1024, 'One gig lowercased' ), - array( '1M', 1024 * 1024, 'One meg uppercased' ), - array( '1m', 1024 * 1024, 'One meg lowercased' ), - array( '1K', 1024, 'One kb uppercased' ), - array( '1k', 1024, 'One kb lowercased' ), - ); - } - -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php deleted file mode 100644 index 505c28c7..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ /dev/null @@ -1,134 +0,0 @@ -assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - function provideNormalTimestamps() { - $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); - return array ( - // TS_UNIX - array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ), - array( -30281104, TS_MW, '19690115123456', 'Negative TS_UNIX to TS_MW' ), - array( $t, TS_UNIX, 979562096, 'TS_UNIX to TS_UNIX' ), - array( $t, TS_DB, '2001-01-15 12:34:56', 'TS_UNIX to TS_DB' ), - - array( $t, TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_ISO_8601_BASIC to TS_DB' ), - - // TS_MW - array( '20010115123456', TS_MW, '20010115123456', 'TS_MW to TS_MW' ), - array( '20010115123456', TS_UNIX, 979562096, 'TS_MW to TS_UNIX' ), - array( '20010115123456', TS_DB, '2001-01-15 12:34:56', 'TS_MW to TS_DB' ), - array( '20010115123456', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_MW to TS_ISO_8601_BASIC' ), - - // TS_DB - array( '2001-01-15 12:34:56', TS_MW, '20010115123456', 'TS_DB to TS_MW' ), - array( '2001-01-15 12:34:56', TS_UNIX, 979562096, 'TS_DB to TS_UNIX' ), - array( '2001-01-15 12:34:56', TS_DB, '2001-01-15 12:34:56', 'TS_DB to TS_DB' ), - array( '2001-01-15 12:34:56', TS_ISO_8601_BASIC, '20010115T123456Z', 'TS_DB to TS_ISO_8601_BASIC' ), - - # rfc2822 section 3.3 - array( '20010115123456', TS_RFC2822, 'Mon, 15 Jan 2001 12:34:56 GMT', 'TS_MW to TS_RFC2822' ), - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - array( ' Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 with leading space to TS_MW' ), - array( '15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 without optional day-of-week to TS_MW' ), - - # FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space - # obs-FWS = 1*WSP *(CRLF 1*WSP) ; Section 4.2 - array( 'Mon, 15 Jan 2001 12:34:56 GMT', TS_MW, '20010115123456', 'TS_RFC2822 to TS_MW' ), - - # WSP = SP / HTAB ; rfc2234 - array( "Mon, 15 Jan\x092001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB to TS_MW' ), - array( "Mon, 15 Jan\x09 \x09 2001 12:34:56 GMT", TS_MW, '20010115123456', 'TS_RFC2822 with HTAB and SP to TS_MW' ), - array( 'Sun, 6 Nov 94 08:49:37 GMT', TS_MW, '19941106084937', 'TS_RFC2822 with obsolete year to TS_MW' ), - ); - } - - /** - * This test checks wfTimestamp() with values outside. - * It needs PHP 64 bits or PHP > 5.1. - * See r74778 and bug 25451 - * @dataProvider provideOldTimestamps - */ - function testOldTimestamps( $input, $format, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); - } - - function provideOldTimestamps() { - return array ( - array( '19011213204554', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:54 GMT', 'Earliest time according to php documentation' ), - array( '20380119031407', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:07 GMT', 'Latest 32 bit time' ), - array( '19011213204552', TS_UNIX, '-2147483648', 'Earliest 32 bit unix time' ), - array( '20380119031407', TS_UNIX, '2147483647', 'Latest 32 bit unix time' ), - array( '19011213204552', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:52 GMT', 'Earliest 32 bit time' ), - array( '19011213204551', TS_RFC2822, 'Fri, 13 Dec 1901 20:45:51 GMT', 'Earliest 32 bit time - 1' ), - array( '20380119031408', TS_RFC2822, 'Tue, 19 Jan 2038 03:14:08 GMT', 'Latest 32 bit time + 1' ), - array( '19011212000000', TS_MW, '19011212000000', 'Convert to itself r74778#c10645' ), - array( '19011213204551', TS_UNIX, '-2147483649', 'Earliest 32 bit unix time - 1' ), - array( '20380119031408', TS_UNIX, '2147483648', 'Latest 32 bit unix time + 1' ), - array( '-2147483649', TS_MW, '19011213204551', '1901 negative unix time to MediaWiki' ), - array( '-5331871504', TS_MW, '18010115123456', '1801 negative unix time to MediaWiki' ), - array( '0117-08-09 12:34:56', TS_RFC2822, 'Tue, 09 Aug 0117 12:34:56 GMT', 'Death of Roman Emperor [[Trajan]]' ), - - /* @todo FIXME: 00 to 101 years are taken as being in [1970-2069] */ - array( '-58979923200', TS_RFC2822, 'Sun, 01 Jan 0101 00:00:00 GMT', '1/1/101' ), - array( '-62135596800', TS_RFC2822, 'Mon, 01 Jan 0001 00:00:00 GMT', 'Year 1' ), - - /* It is not clear if we should generate a year 0 or not - * We are completely off RFC2822 requirement of year being - * 1900 or later. - */ - array( '-62142076800', TS_RFC2822, 'Wed, 18 Oct 0000 00:00:00 GMT', 'ISO 8601:2004 [[year 0]], also called [[1 BC]]' ), - ); - } - - /** - * The Resource Loader uses wfTimestamp() to convert timestamps - * from If-Modified-Since header. Thus it must be able to parse all - * rfc2616 date formats - * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 - * @dataProvider provideHttpDates - */ - function testHttpDate( $input, $output, $desc ) { - $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); - } - - function provideHttpDates() { - return array( - array( 'Sun, 06 Nov 1994 08:49:37 GMT', '19941106084937', 'RFC 822 date' ), - array( 'Sunday, 06-Nov-94 08:49:37 GMT', '19941106084937', 'RFC 850 date' ), - array( 'Sun Nov 6 08:49:37 1994', '19941106084937', "ANSI C's asctime() format" ), - // See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html and r77171 - array( 'Mon, 22 Nov 2010 14:12:42 GMT; length=52626', '20101122141242', 'Netscape extension to HTTP/1.0' ), - ); - } - - /** - * There are a number of assumptions in our codebase where wfTimestamp() - * should give the current date but it is not given a 0 there. See r71751 CR - */ - function testTimestampParameter() { - $now = wfTimestamp( TS_UNIX ); - // We check that wfTimestamp doesn't return false (error) and use a LessThan assert - // for the cases where the test is run in a second boundary. - - $zero = wfTimestamp( TS_UNIX, 0 ); - $this->assertNotEquals( false, $zero ); - $this->assertLessThan( 5, $zero - $now ); - - $empty = wfTimestamp( TS_UNIX, '' ); - $this->assertNotEquals( false, $empty ); - $this->assertLessThan( 5, $empty - $now ); - - $null = wfTimestamp( TS_UNIX, null ); - $this->assertNotEquals( false, $null ); - $this->assertLessThan( 5, $null - $now ); - } -} diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php deleted file mode 100644 index cd1a8dbd..00000000 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ /dev/null @@ -1,120 +0,0 @@ - wfUrlencode() - * - * The function only need a string parameter and might react to IIS7.0 - */ - -class wfUrlencodeTest extends MediaWikiTestCase { - - #### TESTS ############################################################## - - /** @dataProvider provideURLS */ - public function testEncodingUrlWith( $input, $expected ) { - $this->verifyEncodingFor( 'Apache', $input, $expected ); - } - - /** @dataProvider provideURLS */ - public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { - $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); - } - - #### HELPERS ############################################################# - - /** - * Internal helper that actually run the test. - * Called by the public methods testEncodingUrlWith...() - * - */ - private function verifyEncodingFor( $server, $input, $expectations ) { - $expected = $this->extractExpect( $server, $expectations ); - - // save up global - $old = isset($_SERVER['SERVER_SOFTWARE']) - ? $_SERVER['SERVER_SOFTWARE'] - : null - ; - $_SERVER['SERVER_SOFTWARE'] = $server; - wfUrlencode( null ); - - // do the requested test - $this->assertEquals( - $expected, - wfUrlencode( $input ), - "Encoding '$input' for server '$server' should be '$expected'" - ); - - // restore global - if( $old === null ) { - unset( $_SERVER['SERVER_SOFTWARE'] ); - } else { - $_SERVER['SERVER_SOFTWARE'] = $old; - } - wfUrlencode( null ); - } - - /** - * Interprets the provider array. Return expected value depending - * the HTTP server name. - */ - private function extractExpect( $server, $expectations ) { - if( is_string( $expectations ) ) { - return $expectations; - } elseif( is_array( $expectations ) ) { - if( !array_key_exists( $server, $expectations ) ) { - throw new MWException( __METHOD__ . " expectation does not have any value for server name $server. Check the provider array.\n" ); - } else { - return $expectations[$server]; - } - } else { - throw new MWException( __METHOD__ . " given invalid expectation for '$server'. Should be a string or an array( => ).\n" ); - } - } - - - #### PROVIDERS ########################################################### - - /** - * Format is either: - * array( 'input', 'expected' ); - * Or: - * array( 'input', - * array( 'Apache', 'expected' ), - * array( 'Microsoft-IIS/7', 'expected' ), - * ), - * If you want to add other HTTP server name, you will have to add a new - * testing method much like the testEncodingUrlWith() method above. - */ - public function provideURLS() { - return array( - ### RFC 1738 chars - // + is not safe - array( '+', '%2B' ), - // & and = not safe in queries - array( '&', '%26' ), - array( '=', '%3D' ), - - array( ':', array( - 'Apache' => ':', - 'Microsoft-IIS/7' => '%3A', - ) ), - - // remaining chars do not need encoding - array( - ';@$-_.!*', - ';@$-_.!*', - ), - - ### Other tests - // slash remain unchanged. %2F seems to break things - array( '/', '/' ), - - // Other 'funnies' chars - array( '[]', '%5B%5D' ), - array( '<>', '%3C%3E' ), - - // Apostrophe is encoded - array( '\'', '%27' ), - ); - } -} diff --git a/tests/phpunit/includes/HooksTest.php b/tests/phpunit/includes/HooksTest.php deleted file mode 100644 index 2f9d9f8d..00000000 --- a/tests/phpunit/includes/HooksTest.php +++ /dev/null @@ -1,102 +0,0 @@ -assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = $i; - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStaticWithData', 'baz' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - //$foo = 'Foo'; - - unset( $wgHooks['MediaWikiHooksTest001'] ); - - } - - public function testNewStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - - $i = new NothingClass(); - - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStatic' ) ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'fOO', $foo, 'Standard method' ); - $foo = 'Foo'; - - Hooks::register( 'MediaWikiHooksTest001', $i ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'foo', $foo, 'onEventName style' ); - $foo = 'Foo'; - - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStaticWithData', 'baz' ) ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; - - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someStatic' ) ); - - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - $foo = 'Foo'; - } -} - -class NothingClass { - static public function someStatic( &$foo, &$bar ) { - $foo = 'bah'; - return true; - } - - public function someNonStatic( &$foo, &$bar ) { - $foo = 'fOO'; - $bar = 'bAR'; - return true; - } - - public function onMediaWikiHooksTest001( &$foo, &$bar ) { - $foo = 'foo'; - return true; - } - - public function someNonStaticWithData( $foo, &$bar ) { - $bar = $foo; - return true; - } -} diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php deleted file mode 100644 index 135ebc5a..00000000 --- a/tests/phpunit/includes/HtmlTest.php +++ /dev/null @@ -1,580 +0,0 @@ -getNamespaces(); - self::$oldLanguageCode = $wgLanguageCode; - self::$oldHTML5 = $wgHTML5; - - $wgLanguageCode = 'en'; - $wgContLang = $wgLang = Language::factory( $wgLanguageCode ); - - // Hardcode namespaces during test runs, - // so that html output based on existing namespaces - // can be properly evaluated. - $wgContLang->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 14 => 'Category', - 15 => 'Category_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - } - - public function tearDown() { - global $wgLang, $wgContLang, $wgLanguageCode, $wgHTML5; - - // Restore globals - $wgContLang->setNamespaces( self::$oldNamespaces ); - $wgLang = self::$oldLang; - $wgContLang = self::$oldContLang; - $wgLanguageCode = self::$oldLanguageCode; - $wgHTML5 = self::$oldHTML5; - } - - /** - * Wrapper to easily set $wgHTML5 = true. - * Original value will be restored after test completion. - * @todo Move to MediaWikiTestCase - */ - public function enableHTML5() { - global $wgHTML5; - $wgHTML5 = true; - } - /** - * Wrapper to easily set $wgHTML5 = false - * Original value will be restored after test completion. - * @todo Move to MediaWikiTestCase - */ - public function disableHTML5() { - global $wgHTML5; - $wgHTML5 = false; - } - - public function testExpandAttributesSkipsNullAndFalse() { - - ### EMPTY ######## - $this->AssertEmpty( - Html::expandAttributes( array( 'foo' => null ) ), - 'skip keys with null value' - ); - $this->AssertEmpty( - Html::expandAttributes( array( 'foo' => false ) ), - 'skip keys with false value' - ); - $this->AssertNotEmpty( - Html::expandAttributes( array( 'foo' => '' ) ), - 'keep keys with an empty string' - ); - } - - public function testExpandAttributesForBooleans() { - global $wgHtml5; - $this->AssertEquals( - '', - Html::expandAttributes( array( 'selected' => false ) ), - 'Boolean attributes do not generates output when value is false' - ); - $this->AssertEquals( - '', - Html::expandAttributes( array( 'selected' => null ) ), - 'Boolean attributes do not generates output when value is null' - ); - - $this->AssertEquals( - $wgHtml5 ? ' selected=""' : ' selected="selected"', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes skip value output' - ); - $this->AssertEquals( - $wgHtml5 ? ' selected=""' : ' selected="selected"', - Html::expandAttributes( array( 'selected' ) ), - 'Boolean attributes (ex: selected) do not need a value' - ); - } - - /** - * Test for Html::expandAttributes() - * Please note it output a string prefixed with a space! - */ - public function testExpandAttributesVariousExpansions() { - ### NOT EMPTY #### - $this->AssertEquals( - ' empty_string=""', - Html::expandAttributes( array( 'empty_string' => '' ) ), - 'Value with an empty string' - ); - $this->AssertEquals( - ' key="value"', - Html::expandAttributes( array( 'key' => 'value' ) ), - 'Value is a string' - ); - $this->AssertEquals( - ' one="1"', - Html::expandAttributes( array( 'one' => 1 ) ), - 'Value is a numeric one' - ); - $this->AssertEquals( - ' zero="0"', - Html::expandAttributes( array( 'zero' => 0 ) ), - 'Value is a numeric zero' - ); - } - - /** - * Html::expandAttributes has special features for HTML - * attributes that use space separated lists and also - * allows arrays to be used as values. - */ - public function testExpandAttributesListValueAttributes() { - ### STRING VALUES - $this->AssertEquals( - ' class="redundant spaces here"', - Html::expandAttributes( array( 'class' => ' redundant spaces here ' ) ), - 'Normalization should strip redundant spaces' - ); - $this->AssertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => 'foo bar foo bar bar' ) ), - 'Normalization should remove duplicates in string-lists' - ); - ### "EMPTY" ARRAY VALUES - $this->AssertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array() ) ), - 'Value with an empty array' - ); - $this->AssertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( null, '', ' ', ' ' ) ) ), - 'Array with null, empty string and spaces' - ); - ### NON-EMPTY ARRAY VALUES - $this->AssertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo', - 'bar', - 'foo', - 'bar', - 'bar', - ) ) ), - 'Normalization should remove duplicates in the array' - ); - $this->AssertEquals( - ' class="foo bar"', - Html::expandAttributes( array( 'class' => array( - 'foo bar', - 'bar foo', - 'foo', - 'bar bar', - ) ) ), - 'Normalization should remove duplicates in string-lists in the array' - ); - } - - /** - * Test feature added by r96188, let pass attributes values as - * a PHP array. Restricted to class,rel, accesskey. - */ - function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { - $this->assertEquals( - ' class="booltrue one"', - Html::expandAttributes( array( 'class' => array( - 'booltrue' => true, - 'one' => 1, - - # Method use isset() internally, make sure we do discard - # attributes values which have been assigned well known values - 'emptystring' => '', - 'boolfalse' => false, - 'zero' => 0, - 'null' => null, - ))) - ); - } - - /** - * How do we handle duplicate keys in HTML attributes expansion? - * We could pass a "class" the values: 'GREEN' and array( 'GREEN' => false ) - * The later will take precedence. - * - * Feature added by r96188 - */ - function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { - $this->assertEquals( - ' class=""', - Html::expandAttributes( array( 'class' => array( - 'GREEN', - 'GREEN' => false, - 'GREEN', - ))) - ); - } - - function testNamespaceSelector() { - $this->assertEquals( - '', - Html::namespaceSelector(), - 'Basic namespace selector without custom options' - ); - - $this->assertEquals( - ' ' . -'', - Html::namespaceSelector( - array( 'selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:' ), - array( 'name' => 'wpNamespace', 'id' => 'mw-test-namespace' ) - ), - 'Basic namespace selector with custom values' - ); - - $this->assertEquals( - ' ' . -'', - Html::namespaceSelector( - array( 'label' => 'Select a namespace:' ) - ), - 'Basic namespace selector with a custom label but no id attribtue for the ' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'' . "\n" . -'', - Html::namespaceSelector( - array( 'exclude' => array( 0, 1, 3, 100, 101 ) ) - ), - 'Namespace selector namespace filtering.' - ); - } - - function testCanDisableANamespaces() { - $this->assertEquals( -'', - Html::namespaceSelector( array( - 'disable' => array( 0, 1, 2, 3, 4 ) - ) ), - 'Namespace selector namespace disabling' - ); - } - - /** - * @dataProvider providesHtml5InputTypes - */ - function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { - $this->enableHTML5(); - $this->assertEquals( - '', - HTML::element( 'input', array( 'type' => $HTML5InputType ) ), - 'In HTML5, HTML::element() should accept type="' . $HTML5InputType . '"' - ); - } - - /** - * List of input element types values introduced by HTML5 - * Full list at http://www.w3.org/TR/html-markup/input.html - */ - function providesHtml5InputTypes() { - $types = array( - 'datetime', - 'datetime-local', - 'date', - 'month', - 'time', - 'week', - 'number', - 'range', - 'email', - 'url', - 'search', - 'tel', - 'color', - ); - $cases = array(); - foreach( $types as $type ) { - $cases[] = array( $type ); - } - return $cases; - } - - /** - * Test out Html::element drops default value - * @cover Html::dropDefaults - * @dataProvider provideElementsWithAttributesHavingDefaultValues - */ - function testDropDefaults( $expected, $element, $message = '' ) { - $this->enableHTML5(); - $this->assertEquals( $expected, $element, $message ); - } - - function provideElementsWithAttributesHavingDefaultValues() { - # Use cases in a concise format: - # , , [, ] - # Will be mapped to Html::element() - $cases = array(); - - ### Generic cases, match $attribDefault static array - $cases[] = array( '', - 'area', array( 'shape' => 'rect' ) - ); - - $cases[] = array( '', - 'button', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '', - 'button', array( 'formenctype' => 'application/x-www-form-urlencoded' ) - ); - $cases[] = array( '', - 'button', array( 'type' => 'submit' ) - ); - - $cases[] = array( '', - 'canvas', array( 'height' => '150' ) - ); - $cases[] = array( '', - 'canvas', array( 'width' => '300' ) - ); - # Also check with numeric values - $cases[] = array( '', - 'canvas', array( 'height' => 150 ) - ); - $cases[] = array( '', - 'canvas', array( 'width' => 300 ) - ); - - $cases[] = array( '', - 'command', array( 'type' => 'command' ) - ); - - $cases[] = array( '
    ', - 'form', array( 'action' => 'GET' ) - ); - $cases[] = array( '
    ', - 'form', array( 'autocomplete' => 'on' ) - ); - $cases[] = array( '
    ', - 'form', array( 'enctype' => 'application/x-www-form-urlencoded' ) - ); - - $cases[] = array( '', - 'input', array( 'formaction' => 'GET' ) - ); - $cases[] = array( '', - 'input', array( 'type' => 'text' ) - ); - - $cases[] = array( '', - 'keygen', array( 'keytype' => 'rsa' ) - ); - - $cases[] = array( '', - 'link', array( 'media' => 'all' ) - ); - - $cases[] = array( '', - 'menu', array( 'type' => 'list' ) - ); - - $cases[] = array( '', - 'script', array( 'type' => 'text/javascript' ) - ); - - $cases[] = array( '', - 'style', array( 'media' => 'all' ) - ); - $cases[] = array( '', - 'style', array( 'type' => 'text/css' ) - ); - - $cases[] = array( '', - 'textarea', array( 'wrap' => 'soft' ) - ); - - ### SPECIFIC CASES - - # - $cases[] = array( '', - 'link', array( 'type' => 'text/css' ) - ); - - # specific handling - $cases[] = array( '', - 'input', array( 'type' => 'checkbox', 'value' => 'on' ), - 'Default value "on" is stripped of checkboxes', - ); - $cases[] = array( '', - 'input', array( 'type' => 'radio', 'value' => 'on' ), - 'Default value "on" is stripped of radio buttons', - ); - $cases[] = array( '', - 'input', array( 'type' => 'submit', 'value' => 'Submit' ), - 'Default value "Submit" is kept on submit buttons (for possible l10n issues)', - ); - $cases[] = array( '', - 'input', array( 'type' => 'color', 'value' => '' ), - ); - $cases[] = array( '', - 'input', array( 'type' => 'range', 'value' => '' ), - ); - - # ', - 'select', array( 'size' => '4', 'multiple' => true ), - ); - # .. with numeric value - $cases[] = array( '', - 'select', array( 'size' => 4, 'multiple' => true ), - ); - $cases[] = array( '', - 'select', array( 'size' => '1', 'multiple' => false ), - ); - # .. with numeric value - $cases[] = array( '', - 'select', array( 'size' => 1, 'multiple' => false ), - ); - - # Passing an array as value - $cases[] = array( '', - 'a', array( 'class' => array( 'css-class-one', 'css-class-two' ) ), - "dropDefaults accepts values given as an array" - ); - - # FIXME: doDropDefault should remove defaults given in an array - # Expected should be '' - $cases[] = array( '', - 'a', array( 'class' => array( '', '' ) ), - "dropDefaults accepts values given as an array" - ); - - - # Craft the Html elements - $ret = array(); - foreach( $cases as $case ) { - $ret[] = array( - $case[0], - Html::element( $case[1], $case[2] ) - ); - } - return $ret; - } - - public function testFormValidationBlacklist() { - $this->assertEmpty( - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 2 ) ), - 'Blacklist form validation attributes.' - ); - $this->assertEquals( - ' step="any"', - Html::expandAttributes( array( 'min' => 1, 'max' => 100, 'pattern' => 'abc', 'required' => true, 'step' => 'any' ) ), - "Allow special case 'step=\"any\"'." - ); - } - -} diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php deleted file mode 100644 index 263383f1..00000000 --- a/tests/phpunit/includes/HttpTest.php +++ /dev/null @@ -1,180 +0,0 @@ -assertEquals( $expected, $ok, $msg ); - } - - function cookieDomains() { - return array( - array( false, "org"), - array( false, ".org"), - array( true, "wikipedia.org"), - array( true, ".wikipedia.org"), - array( false, "co.uk" ), - array( false, ".co.uk" ), - array( false, "gov.uk" ), - array( false, ".gov.uk" ), - array( true, "supermarket.uk" ), - array( false, "uk" ), - array( false, ".uk" ), - array( false, "127.0.0." ), - array( false, "127." ), - array( false, "127.0.0.1." ), - array( true, "127.0.0.1" ), - array( false, "333.0.0.1" ), - array( true, "example.com" ), - array( false, "example.com." ), - array( true, ".example.com" ), - - array( true, ".example.com", "www.example.com" ), - array( false, "example.com", "www.example.com" ), - array( true, "127.0.0.1", "127.0.0.1" ), - array( false, "127.0.0.1", "localhost" ), - ); - } - - /** - * Test Http::isValidURI() - * @bug 27854 : Http::isValidURI is too lax - * @dataProvider provideURI - */ - function testIsValidUri( $expect, $URI, $message = '' ) { - $this->assertEquals( - $expect, - (bool) Http::isValidURI( $URI ), - $message - ); - } - - /** - * Feeds URI to test a long regular expression in Http::isValidURI - */ - function provideURI() { - /** Format: 'boolean expectation', 'URI to test', 'Optional message' */ - return array( - array( false, '¿non sens before!! http://a', 'Allow anything before URI' ), - - # (http|https) - only two schemes allowed - array( true, 'http://www.example.org/' ), - array( true, 'https://www.example.org/' ), - array( true, 'http://www.example.org', 'URI without directory' ), - array( true, 'http://a', 'Short name' ), - array( true, 'http://étoile', 'Allow UTF-8 in hostname' ), # 'étoile' is french for 'star' - array( false, '\\host\directory', 'CIFS share' ), - array( false, 'gopher://host/dir', 'Reject gopher scheme' ), - array( false, 'telnet://host', 'Reject telnet scheme' ), - - # :\/\/ - double slashes - array( false, 'http//example.org', 'Reject missing colon in protocol' ), - array( false, 'http:/example.org', 'Reject missing slash in protocol' ), - array( false, 'http:example.org', 'Must have two slashes' ), - # Following fail since hostname can be made of anything - array( false, 'http:///example.org', 'Must have exactly two slashes, not three' ), - - # (\w+:{0,1}\w*@)? - optional user:pass - array( true, 'http://user@host', 'Username provided' ), - array( true, 'http://user:@host', 'Username provided, no password' ), - array( true, 'http://user:pass@host', 'Username and password provided' ), - - # (\S+) - host part is made of anything not whitespaces - array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ), - array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ), - - # (:[0-9]+)? - port number - array( true, 'http://example.org:80/' ), - array( true, 'https://example.org:80/' ), - array( true, 'http://example.org:443/' ), - array( true, 'https://example.org:443/' ), - - # Part after the hostname is / or / with something else - array( true, 'http://example/#' ), - array( true, 'http://example/!' ), - array( true, 'http://example/:' ), - array( true, 'http://example/.' ), - array( true, 'http://example/?' ), - array( true, 'http://example/+' ), - array( true, 'http://example/=' ), - array( true, 'http://example/&' ), - array( true, 'http://example/%' ), - array( true, 'http://example/@' ), - array( true, 'http://example/-' ), - array( true, 'http://example//' ), - array( true, 'http://example/&' ), - - # Fragment - array( true, 'http://exam#ple.org', ), # This one is valid, really! - array( true, 'http://example.org:80#anchor' ), - array( true, 'http://example.org/?id#anchor' ), - array( true, 'http://example.org/?#anchor' ), - - array( false, 'http://a ¿non !!sens after', 'Allow anything after URI' ), - ); - } - - /** - * Warning: - * - * These tests are for code that makes use of an artifact of how CURL - * handles header reporting on redirect pages, and will need to be - * rewritten when bug 29232 is taken care of (high-level handling of - * HTTP redirects). - */ - function testRelativeRedirections() { - $h = new MWHttpRequestTester( 'http://oldsite/file.ext' ); - # Forge a Location header - $h->setRespHeaders( 'location', array( - 'http://newsite/file.ext', - '/newfile.ext', - ) - ); - # Verify we correctly fix the Location - $this->assertEquals( - 'http://newsite/newfile.ext', - $h->getFinalUrl(), - "Relative file path Location: interpreted as full URL" - ); - - $h->setRespHeaders( 'location', array( - 'https://oldsite/file.ext' - ) - ); - $this->assertEquals( - 'https://oldsite/file.ext', - $h->getFinalUrl(), - "Location to the HTTPS version of the site" - ); - - $h->setRespHeaders( 'location', array( - '/anotherfile.ext', - 'http://anotherfile/hoster.ext', - 'https://anotherfile/hoster.ext' - ) - ); - $this->assertEquals( - 'https://anotherfile/hoster.ext', - $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!") - ); - } -} - -/** - * Class to let us overwrite MWHttpREquest respHeaders variable - */ -class MWHttpRequestTester extends MWHttpRequest { - function setRespHeaders( $name, $value ) { - $this->respHeaders[$name] = $value ; - } -} diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php deleted file mode 100644 index f50b2fe9..00000000 --- a/tests/phpunit/includes/IPTest.php +++ /dev/null @@ -1,542 +0,0 @@ -assertFalse( IP::isIPAddress( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPAddress( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPAddress( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPAddress( 'abc' ), 'Garbage IP string' ); - $this->assertFalse( IP::isIPAddress( ':' ), 'Single ":" is not an IP' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::1'), 'IPv6 with a double :: occurrence' ); - $this->assertFalse( IP::isIPAddress( '2001:0DB8::A:1::'), 'IPv6 with a double :: occurrence, last at end' ); - $this->assertFalse( IP::isIPAddress( '::2001:0DB8::5:1'), 'IPv6 with a double :: occurrence, firt at beginning' ); - $this->assertFalse( IP::isIPAddress( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPAddress( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPAddress( '.24.52.13' ), 'IPv4 starts with period' ); - $this->assertFalse( IP::isIPAddress( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPAddress( '::' ), 'RFC 4291 IPv6 Unspecified Address' ); - $this->assertTrue( IP::isIPAddress( '::1' ), 'RFC 4291 IPv6 Loopback Address' ); - $this->assertTrue( IP::isIPAddress( '74.24.52.13/20', 'IPv4 range' ) ); - $this->assertTrue( IP::isIPAddress( 'fc:100:a:d:1:e:ac:0/24' ), 'IPv6 range' ); - $this->assertTrue( IP::isIPAddress( 'fc::100:a:d:1:e:ac/96' ), 'IPv6 range with "::"' ); - - $validIPs = array( 'fc:100::', 'fc:100:a:d:1:e:ac::', 'fc::100', '::fc:100:a:d:1:e:ac', - '::fc', 'fc::100:a:d:1:e:ac', 'fc:100:a:d:1:e:ac:0', '124.24.52.13', '1.24.52.13' ); - foreach ( $validIPs as $ip ) { - $this->assertTrue( IP::isIPAddress( $ip ), "$ip is a valid IP address" ); - } - } - - /** - * @covers IP::isIPv6 - */ - public function testisIPv6() { - $this->assertFalse( IP::isIPv6( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isIPv6( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isIPv6( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isIPv6( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - - $this->assertFalse( IP::isIPv6( ':::' ) ); - $this->assertFalse( IP::isIPv6( '::0:' ), 'IPv6 ending in a lone ":"' ); - - $this->assertTrue( IP::isIPv6( '::' ), 'IPv6 zero address' ); - $this->assertTrue( IP::isIPv6( '::0' ) ); - $this->assertTrue( IP::isIPv6( '::fc' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e' ) ); - $this->assertTrue( IP::isIPv6( '::fc:100:a:d:1:e:ac' ) ); - - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( '::fc:100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertFalse( IP::isIPv6( ':fc::100' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc::100:' ), 'IPv6 ending with lone ":"' ); - $this->assertFalse( IP::isIPv6( 'fc:::100' ), 'IPv6 with ":::" in the middle' ); - - $this->assertTrue( IP::isIPv6( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d', 'IPv6 with "::" and 4 words' ) ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e' ), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isIPv6( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - $this->assertTrue( IP::isIPv6( '2001::df'), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isIPv6( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' ); - - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0' ), 'IPv6 with "::" and 8 words' ); - $this->assertFalse( IP::isIPv6( 'fc::100:a:d:1:e:ac:0:1' ), 'IPv6 with 9 words' ); - - $this->assertTrue( IP::isIPv6( 'fc:100:a:d:1:e:ac:0' ) ); - } - - /** - * @covers IP::isIPv4 - */ - public function testisIPv4() { - $this->assertFalse( IP::isIPv4( false ), 'Boolean false is not an IP' ); - $this->assertFalse( IP::isIPv4( true ), 'Boolean true is not an IP' ); - $this->assertFalse( IP::isIPv4( "" ), 'Empty string is not an IP' ); - $this->assertFalse( IP::isIPv4( 'abc' ) ); - $this->assertFalse( IP::isIPv4( ':' ) ); - $this->assertFalse( IP::isIPv4( '124.24.52' ), 'IPv4 not enough quads' ); - $this->assertFalse( IP::isIPv4( '24.324.52.13' ), 'IPv4 out of range' ); - $this->assertFalse( IP::isIPv4( '.24.52.13' ), 'IPv4 starts with period' ); - - $this->assertTrue( IP::isIPv4( '124.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '1.24.52.13' ) ); - $this->assertTrue( IP::isIPv4( '74.24.52.13/20', 'IPv4 range' ) ); - } - - /** - * @covers IP::isValid - */ - public function testValidIPs() { - foreach ( range( 0, 255 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv4 address" ); - } - } - foreach ( range( 0x0, 0xFFFF, 0xF ) as $i ) { - $a = sprintf( "%04x", $i ); - $b = sprintf( "%03x", $i ); - $c = sprintf( "%02x", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv6 address" ); - } - } - // test with some abbreviations - $this->assertFalse( IP::isValid( ':fc:100::' ), 'IPv6 starting with lone ":"' ); - $this->assertFalse( IP::isValid( 'fc:100:::' ), 'IPv6 ending with a ":::"' ); - $this->assertFalse( IP::isValid( 'fc:300' ), 'IPv6 with only 2 words' ); - $this->assertFalse( IP::isValid( 'fc:100:300' ), 'IPv6 with only 3 words' ); - - $this->assertTrue( IP::isValid( 'fc:100::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e::' ) ); - $this->assertTrue( IP::isValid( 'fc:100:a:d:1:e:ac::' ) ); - - $this->assertTrue( IP::isValid( 'fc::100' ), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a' ), 'IPv6 with "::" and 3 words' ); - $this->assertTrue( IP::isValid( '2001::df'), 'IPv6 with "::" and 2 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df'), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( '2001:5c0:1400:a::df:2'), 'IPv6 with "::" and 6 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1' ), 'IPv6 with "::" and 5 words' ); - $this->assertTrue( IP::isValid( 'fc::100:a:d:1:e:ac' ), 'IPv6 with "::" and 7 words' ); - - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0::' ), 'IPv6 with 8 words ending with "::"' ); - $this->assertFalse( IP::isValid( 'fc:100:a:d:1:e:ac:0:1::' ), 'IPv6 with 9 words ending with "::"' ); - } - - /** - * @covers IP::isValid - */ - public function testInvalidIPs() { - // Out of range... - foreach ( range( 256, 999 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); - } - } - foreach ( range( 'g', 'z' ) as $i ) { - $a = sprintf( "%04s", $i ); - $b = sprintf( "%03s", $i ); - $c = sprintf( "%02s", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f:$f:$f:$f:$f:$f:$f:$f"; - $this->assertFalse( IP::isValid( $ip ) , "$ip is not a valid IPv6 address" ); - } - } - // Have CIDR - $ipCIDRs = array( - '212.35.31.121/32', - '212.35.31.121/18', - '212.35.31.121/24', - '::ff:d:321:5/96', - 'ff::d3:321:5/116', - 'c:ff:12:1:ea:d:321:5/120', - ); - foreach ( $ipCIDRs as $i ) { - $this->assertFalse( IP::isValid( $i ), - "$i is an invalid IP address because it is a block" ); - } - // Incomplete/garbage - $invalid = array( - 'www.xn--var-xla.net', - '216.17.184.G', - '216.17.184.1.', - '216.17.184', - '216.17.184.', - '256.17.184.1' - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValid( $i ), "$i is an invalid IP address" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testValidBlocks() { - $valid = array( - '116.17.184.5/32', - '0.17.184.5/30', - '16.17.184.1/24', - '30.242.52.14/1', - '10.232.52.13/8', - '30.242.52.14/0', - '::e:f:2001/96', - '::c:f:2001/128', - '::10:f:2001/70', - '::fe:f:2001/1', - '::6d:f:2001/8', - '::fe:f:2001/0', - ); - foreach ( $valid as $i ) { - $this->assertTrue( IP::isValidBlock( $i ), "$i is a valid IP block" ); - } - } - - /** - * @covers IP::isValidBlock - */ - public function testInvalidBlocks() { - $invalid = array( - '116.17.184.5/33', - '0.17.184.5/130', - '16.17.184.1/-1', - '10.232.52.13/*', - '7.232.52.13/ab', - '11.232.52.13/', - '::e:f:2001/129', - '::c:f:2001/228', - '::10:f:2001/-1', - '::6d:f:2001/*', - '::86:f:2001/ab', - '::23:f:2001/', - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValidBlock( $i ), "$i is not a valid IP block" ); - } - } - - /** - * Improve IP::sanitizeIP() code coverage - * @todo Most probably incomplete - */ - public function testSanitizeIP() { - $this->assertNull( IP::sanitizeIP('') ); - $this->assertNull( IP::sanitizeIP(' ') ); - } - - /** - * test wrapper around ip2long which might return -1 or false depending on PHP version - * @covers IP::toUnsigned - */ - public function testip2longWrapper() { - // @todo FIXME: Add more tests ? - $this->assertEquals( pow(2,32) - 1, IP::toUnsigned( '255.255.255.255' )); - $i = 'IN.VA.LI.D'; - $this->assertFalse( IP::toUnSigned( $i ) ); - } - - /** - * @covers IP::isPublic - */ - public function testPrivateIPs() { - $private = array( 'fc00::3', 'fc00::ff', '::1', '10.0.0.1', '172.16.0.1', '192.168.0.1' ); - foreach ( $private as $p ) { - $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); - } - $public = array( '2001:5c0:1000:a::133', 'fc::3', '00FC::' ); - foreach ( $public as $p ) { - $this->assertTrue( IP::isPublic( $p ), "$p is a public IP address" ); - } - } - - // Private wrapper used to test CIDR Parsing. - private function assertFalseCIDR( $CIDR, $msg='' ) { - $ff = array( false, false ); - $this->assertEquals( $ff, IP::parseCIDR( $CIDR ), $msg ); - } - - // Private wrapper to test network shifting using only dot notation - private function assertNet( $expected, $CIDR ) { - $parse = IP::parseCIDR( $CIDR ); - $this->assertEquals( $expected, long2ip( $parse[0] ), "network shifting $CIDR" ); - } - - /** - * @covers IP::hexToQuad - */ - public function testHexToQuad() { - $this->assertEquals( '0.0.0.1' , IP::hexToQuad( '00000001' ) ); - $this->assertEquals( '255.0.0.0' , IP::hexToQuad( 'FF000000' ) ); - $this->assertEquals( '255.255.255.255', IP::hexToQuad( 'FFFFFFFF' ) ); - $this->assertEquals( '10.188.222.255' , IP::hexToQuad( '0ABCDEFF' ) ); - // hex not left-padded... - $this->assertEquals( '0.0.0.0' , IP::hexToQuad( '0' ) ); - $this->assertEquals( '0.0.0.1' , IP::hexToQuad( '1' ) ); - $this->assertEquals( '0.0.0.255' , IP::hexToQuad( 'FF' ) ); - $this->assertEquals( '0.0.255.0' , IP::hexToQuad( 'FF00' ) ); - } - - /** - * @covers IP::hexToOctet - */ - public function testHexToOctet() { - $this->assertEquals( '0:0:0:0:0:0:0:1', - IP::hexToOctet( '00000000000000000000000000000001' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF:3', - IP::hexToOctet( '00000000000000000000000000FF0003' ) ); - $this->assertEquals( '0:0:0:0:0:0:FF00:6', - IP::hexToOctet( '000000000000000000000000FF000006' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', - IP::hexToOctet( '000000000000000000000000FCCFFAFF' ) ); - $this->assertEquals( 'FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - IP::hexToOctet( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' ) ); - // hex not left-padded... - $this->assertEquals( '0:0:0:0:0:0:0:0' , IP::hexToOctet( '0' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:1' , IP::hexToOctet( '1' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FF' , IP::hexToOctet( 'FF' ) ); - $this->assertEquals( '0:0:0:0:0:0:0:FFD0' , IP::hexToOctet( 'FFD0' ) ); - $this->assertEquals( '0:0:0:0:0:0:FA00:0' , IP::hexToOctet( 'FA000000' ) ); - $this->assertEquals( '0:0:0:0:0:0:FCCF:FAFF', IP::hexToOctet( 'FCCFFAFF' ) ); - } - - /** - * IP::parseCIDR() returns an array containing a signed IP address - * representing the network mask and the bit mask. - * @covers IP::parseCIDR - */ - function testCIDRParsing() { - $this->assertFalseCIDR( '192.0.2.0' , "missing mask" ); - $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); - - // Verify if statement - $this->assertFalseCIDR( '256.0.0.0/32', "invalid net" ); - $this->assertFalseCIDR( '192.0.2.0/AA', "mask not numeric" ); - $this->assertFalseCIDR( '192.0.2.0/-1', "mask < 0" ); - $this->assertFalseCIDR( '192.0.2.0/33', "mask > 32" ); - - // Check internal logic - # 0 mask always result in array(0,0) - $this->assertEquals( array( 0, 0 ), IP::parseCIDR('192.0.0.2/0') ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR('0.0.0.0/0') ); - $this->assertEquals( array( 0, 0 ), IP::parseCIDR('255.255.255.255/0') ); - - // @todo FIXME: Add more tests. - - # This part test network shifting - $this->assertNet( '192.0.0.0' , '192.0.0.2/24' ); - $this->assertNet( '192.168.5.0', '192.168.5.13/24'); - $this->assertNet( '10.0.0.160' , '10.0.0.161/28' ); - $this->assertNet( '10.0.0.0' , '10.0.0.3/28' ); - $this->assertNet( '10.0.0.0' , '10.0.0.3/30' ); - $this->assertNet( '10.0.0.4' , '10.0.0.4/30' ); - $this->assertNet( '172.17.32.0', '172.17.35.48/21' ); - $this->assertNet( '10.128.0.0' , '10.135.0.0/9' ); - $this->assertNet( '134.0.0.0' , '134.0.5.1/8' ); - } - - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeOnValidIp() { - $this->assertEquals( '192.0.2.152', IP::canonicalize( '192.0.2.152' ), - 'Canonicalization of a valid IP returns it unchanged' ); - } - - /** - * @covers IP::canonicalize - */ - public function testIPCanonicalizeMappedAddress() { - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::ffff:192.0.2.152' ) - ); - $this->assertEquals( - '192.0.2.152', - IP::canonicalize( '::192.0.2.152' ) - ); - } - - /** - * Issues there are most probably from IP::toHex() or IP::parseRange() - * @covers IP::isInRange - * @dataProvider provideIPsAndRanges - */ - public function testIPIsInRange( $expected, $addr, $range, $message = '' ) { - $this->assertEquals( - $expected, - IP::isInRange( $addr, $range ), - $message - ); - } - - /** Provider for testIPIsInRange() */ - function provideIPsAndRanges() { - # Format: (expected boolean, address, range, optional message) - return array( - # IPv4 - array( true , '192.0.2.0' , '192.0.2.0/24', 'Network address' ), - array( true , '192.0.2.77' , '192.0.2.0/24', 'Simple address' ), - array( true , '192.0.2.255' , '192.0.2.0/24', 'Broadcast address' ), - - array( false, '0.0.0.0' , '192.0.2.0/24' ), - array( false, '255.255.255' , '192.0.2.0/24' ), - - # IPv6 - array( false, '::1' , '2001:DB8::/32' ), - array( false, '::' , '2001:DB8::/32' ), - array( false, 'FE80::1', '2001:DB8::/32' ), - - array( true , '2001:DB8::' , '2001:DB8::/32' ), - array( true , '2001:0DB8::' , '2001:DB8::/32' ), - array( true , '2001:DB8::1' , '2001:DB8::/32' ), - array( true , '2001:0DB8::1', '2001:DB8::/32' ), - array( true , '2001:0DB8:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF', - '2001:DB8::/32' ), - - array( false, '2001:0DB8:F::', '2001:DB8::/96' ), - ); - } - - /** - * Test for IP::splitHostAndPort(). - * @dataProvider provideSplitHostAndPort - */ - function testSplitHostAndPort( $expected, $input, $description ) { - $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); - } - - /** - * Provider for IP::splitHostAndPort() - */ - function provideSplitHostAndPort() { - return array( - array( false, '[', 'Unclosed square bracket' ), - array( false, '[::', 'Unclosed square bracket 2' ), - array( array( '::', false ), '::', 'Bare IPv6 0' ), - array( array( '::1', false ), '::1', 'Bare IPv6 1' ), - array( array( '::', false ), '[::]', 'Bracketed IPv6 0' ), - array( array( '::1', false ), '[::1]', 'Bracketed IPv6 1' ), - array( array( '::1', 80 ), '[::1]:80', 'Bracketed IPv6 with port' ), - array( false, '::x', 'Double colon but no IPv6' ), - array( array( 'x', 80 ), 'x:80', 'Hostname and port' ), - array( false, 'x:x', 'Hostname and invalid port' ), - array( array( 'x', false ), 'x', 'Plain hostname' ) - ); - } - - /** - * Test for IP::combineHostAndPort() - * @dataProvider provideCombineHostAndPort - */ - function testCombineHostAndPort( $expected, $input, $description ) { - list( $host, $port, $defaultPort ) = $input; - $this->assertEquals( - $expected, - IP::combineHostAndPort( $host, $port, $defaultPort ), - $description ); - } - - /** - * Provider for IP::combineHostAndPort() - */ - function provideCombineHostAndPort() { - return array( - array( '[::1]', array( '::1', 2, 2 ), 'IPv6 default port' ), - array( '[::1]:2', array( '::1', 2, 3 ), 'IPv6 non-default port' ), - array( 'x', array( 'x', 2, 2 ), 'Normal default port' ), - array( 'x:2', array( 'x', 2, 3 ), 'Normal non-default port' ), - ); - } - - /** - * Test for IP::sanitizeRange() - * @dataProvider provideIPCIDRs - */ - function testSanitizeRange( $input, $expected, $description ) { - $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); - } - - /** - * Provider for IP::testSanitizeRange() - */ - function provideIPCIDRs() { - return array( - array( '35.56.31.252/16', '35.56.0.0/16', 'IPv4 range' ), - array( '135.16.21.252/24', '135.16.21.0/24', 'IPv4 range' ), - array( '5.36.71.252/32', '5.36.71.252/32', 'IPv4 silly range' ), - array( '5.36.71.252', '5.36.71.252', 'IPv4 non-range' ), - array( '0:1:2:3:4:c5:f6:7/96', '0:1:2:3:4:C5:0:0/96', 'IPv6 range' ), - array( '0:1:2:3:4:5:6:7/120', '0:1:2:3:4:5:6:0/120', 'IPv6 range' ), - array( '0:e1:2:3:4:5:e6:7/128', '0:E1:2:3:4:5:E6:7/128', 'IPv6 silly range' ), - array( '0:c1:A2:3:4:5:c6:7', '0:C1:A2:3:4:5:C6:7', 'IPv6 non range' ), - ); - } - - /** - * Test for IP::prettifyIP() - * @dataProvider provideIPsToPrettify - */ - function testPrettifyIP( $ip, $prettified ) { - $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); - } - - /** - * Provider for IP::testPrettifyIP() - */ - function provideIPsToPrettify() { - return array( - array( '0:0:0:0:0:0:0:0', '::' ), - array( '0:0:0::0:0:0', '::' ), - array( '0:0:0:1:0:0:0:0', '0:0:0:1::' ), - array( '0:0::f', '::f' ), - array( '0::0:0:0:33:fef:b', '::33:fef:b' ), - array( '3f:535:0:0:0:0:e:fbb', '3f:535::e:fbb' ), - array( '0:0:fef:0:0:0:e:fbb', '0:0:fef::e:fbb' ), - array( 'abbc:2004::0:0:0:0', 'abbc:2004::' ), - array( 'cebc:2004:f:0:0:0:0:0', 'cebc:2004:f::' ), - array( '0:0:0:0:0:0:0:0/16', '::/16' ), - array( '0:0:0::0:0:0/64', '::/64' ), - array( '0:0::f/52', '::f/52' ), - array( '::0:0:33:fef:b/52', '::33:fef:b/52' ), - array( '3f:535:0:0:0:0:e:fbb/48', '3f:535::e:fbb/48' ), - array( '0:0:fef:0:0:0:e:fbb/96', '0:0:fef::e:fbb/96' ), - array( 'abbc:2004:0:0::0:0/40', 'abbc:2004::/40' ), - array( 'aebc:2004:f:0:0:0:0:0/80', 'aebc:2004:f::/80' ), - ); - } -} diff --git a/tests/phpunit/includes/JsonTest.php b/tests/phpunit/includes/JsonTest.php deleted file mode 100644 index 75dd18d5..00000000 --- a/tests/phpunit/includes/JsonTest.php +++ /dev/null @@ -1,33 +0,0 @@ -assertNotEquals( - '\ud840\udc00', - strtolower( FormatJson::encode( "\xf0\xa0\x80\x80" ) ), - 'Test encoding an broken json_encode character (U+20000)' - ); - - - } - - function testDecodeVarTypes() { - - $this->assertInternalType( - 'object', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}' ), - 'Default to object' - ); - - $this->assertInternalType( - 'array', - FormatJson::decode( '{"Name": "Cheeso", "Rank": 7}', true ), - 'Optional array' - ); - - } - -} - diff --git a/tests/phpunit/includes/LanguageConverterTest.php b/tests/phpunit/includes/LanguageConverterTest.php deleted file mode 100644 index baf28b07..00000000 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ /dev/null @@ -1,130 +0,0 @@ -lang = new LanguageToTest(); - $this->lc = new TestConverter( $this->lang, 'tg', - array( 'tg', 'tg-latn' ) ); - } - - function tearDown() { - global $wgMemc; - unset( $wgMemc ); - unset( $this->lc ); - unset( $this->lang ); - parent::tearDown(); - } - - function testGetPreferredVariantDefaults() { - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantHeaders() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantHeaderWeight() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantHeaderWeight2() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantHeaderMulti() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantUserOption() { - global $wgUser; - - $wgUser = new User; - $wgUser->load(); // from 'defaults' - $wgUser->mId = 1; - $wgUser->mDataLoaded = true; - $wgUser->mOptionsLoaded = true; - $wgUser->setOption( 'variant', 'tg-latn' ); - - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantHeaderUserVsUrl() { - global $wgRequest, $wgUser, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgRequest->setVal( 'variant', 'tg' ); - $wgUser = User::newFromId( "admin" ); - $wgUser->setId( 1 ); - $wgUser->mFrom = 'defaults'; - $wgUser->mOptionsLoaded = true; - $wgUser->setOption( 'variant', 'tg-latn' ); // The user's data is ignored - // because the variant is set in the URL. - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } - - - function testGetPreferredVariantDefaultLanguageVariant() { - global $wgDefaultLanguageVariant; - - $wgDefaultLanguageVariant = 'tg-latn'; - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); - } - - function testGetPreferredVariantDefaultLanguageVsUrlVariant() { - global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgDefaultLanguageVariant = 'tg'; - $wgRequest->setVal( 'variant', null ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); - } -} - -/** - * Test converter (from Tajiki to latin orthography) - */ -class TestConverter extends LanguageConverter { - private $table = array( - 'б' => 'b', - 'в' => 'v', - 'г' => 'g', - ); - - function loadDefaultTables() { - $this->mTables = array( - 'tg-latn' => new ReplacementArray( $this->table ), - 'tg' => new ReplacementArray() - ); - } - -} - -class LanguageToTest extends Language { - function __construct() { - parent::__construct(); - $variants = array( 'tg', 'tg-latn' ); - $this->mConverter = new TestConverter( $this, 'tg', $variants ); - } -} diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php deleted file mode 100644 index e467f3cd..00000000 --- a/tests/phpunit/includes/LicensesTest.php +++ /dev/null @@ -1,22 +0,0 @@ - 'FooField', - 'type' => 'select', - 'section' => 'description', - 'id' => 'wpLicense', - 'label' => 'A label text', # Note can't test label-message because $wgOut is not defined - 'name' => 'AnotherName', - 'licenses' => $str, - ) ); - $this->assertThat( $lc, $this->isInstanceOf( 'Licenses' ) ); - } -} diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php deleted file mode 100644 index 49462001..00000000 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ /dev/null @@ -1,154 +0,0 @@ -tablesUsed = array_merge ( $this->tablesUsed, - array( 'interwiki', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - function setUp() { - $dbw = wfGetDB( DB_MASTER ); - $dbw->replace( 'interwiki', - array('iw_prefix'), - array( 'iw_prefix' => 'linksupdatetest', - 'iw_url' => 'http://testing.com/wiki/$1', - 'iw_api' => 'http://testing.com/w/api.php', - 'iw_local' => 0, - 'iw_trans' => 0, - 'iw_wikiid' => 'linksupdatetest', - ) ); - } - - protected function makeTitleAndParserOutput( $name, $id ) { - $t = Title::newFromText( $name ); - $t->mArticleID = $id; # XXX: this is fugly - - $po = new ParserOutput(); - $po->setTitleText( $t->getPrefixedText() ); - - return array( $t, $po ); - } - - public function testUpdate_pagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLink( Title::newFromText( "Foo" ) ); - $po->addLink( Title::newFromText( "Special:Foo" ) ); // special namespace should be ignored - $po->addLink( Title::newFromText( "linksupdatetest:Foo" ) ); // interwiki link should be ignored - $po->addLink( Title::newFromText( "#Foo" ) ); // hash link should be ignored - - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( - array( NS_MAIN, 'Foo' ), - ) ); - - $po = new ParserOutput(); - $po->setTitleText( $t->getPrefixedText() ); - - $po->addLink( Title::newFromText( "Bar" ) ); - - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( - array( NS_MAIN, 'Bar' ), - ) ); - } - - public function testUpdate_externallinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addExternalLink( "http://testing.com/wiki/Foo" ); - - $this->assertLinksUpdate( $t, $po, 'externallinks', 'el_to, el_index', 'el_from = 111', array( - array( 'http://testing.com/wiki/Foo', 'http://com.testing./wiki/Foo' ), - ) ); - } - - public function testUpdate_categorylinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addCategory( "Foo", "FOO" ); - - $this->assertLinksUpdate( $t, $po, 'categorylinks', 'cl_to, cl_sortkey', 'cl_from = 111', array( - array( 'Foo', "FOO\nTESTING" ), - ) ); - } - - public function testUpdate_iwlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $target = Title::makeTitleSafe( NS_MAIN, "Foo", '', 'linksupdatetest' ); - $po->addInterwikiLink( $target ); - - $this->assertLinksUpdate( $t, $po, 'iwlinks', 'iwl_prefix, iwl_title', 'iwl_from = 111', array( - array( 'linksupdatetest', 'Foo' ), - ) ); - } - - public function testUpdate_templatelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addTemplate( Title::newFromText( "Template:Foo" ), 23, 42 ); - - $this->assertLinksUpdate( $t, $po, 'templatelinks', 'tl_namespace, tl_title', 'tl_from = 111', array( - array( NS_TEMPLATE, 'Foo' ), - ) ); - } - - public function testUpdate_imagelinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addImage( "Foo.png" ); - - - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( - array( 'Foo.png' ), - ) ); - } - - public function testUpdate_langlinks() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->addLanguageLink( Title::newFromText( "en:Foo" ) ); - - - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( - array( 'En', 'Foo' ), - ) ); - } - - public function testUpdate_page_props() { - list( $t, $po ) = $this->makeTitleAndParserOutput( "Testing", 111 ); - - $po->setProperty( "foo", "bar" ); - - $this->assertLinksUpdate( $t, $po, 'page_props', 'pp_propname, pp_value', 'pp_page = 111', array( - array( 'foo', 'bar' ), - ) ); - } - - #@todo: test recursive, too! - - protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, Array $expectedRows ) { - $update = new LinksUpdate( $title, $parserOutput ); - - $update->doUpdate(); - - $this->assertSelect( $table, $fields, $condition, $expectedRows ); - } -} - diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php deleted file mode 100644 index 5b26b89c..00000000 --- a/tests/phpunit/includes/LocalFileTest.php +++ /dev/null @@ -1,108 +0,0 @@ - 'test', - 'directory' => '/testdir', - 'url' => '/testurl', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'cont1' => "/testdir/local-backend/tempimages/cont1", - 'cont2' => "/testdir/local-backend/tempimages/cont2" - ) - ) ) - ); - $this->repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); - $this->repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); - $this->repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); - $this->file_hl0 = $this->repo_hl0->newFile( 'test!' ); - $this->file_hl2 = $this->repo_hl2->newFile( 'test!' ); - $this->file_lc = $this->repo_lc->newFile( 'test!' ); - } - - function testGetHashPath() { - $this->assertEquals( '', $this->file_hl0->getHashPath() ); - $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() ); - $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() ); - } - - function testGetRel() { - $this->assertEquals( 'Test!', $this->file_hl0->getRel() ); - $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() ); - $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() ); - } - - function testGetUrlRel() { - $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() ); - $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() ); - $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() ); - } - - function testGetArchivePath() { - $this->assertEquals( 'mwstore://local-backend/test-public/archive', $this->file_hl0->getArchivePath() ); - $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2', $this->file_hl2->getArchivePath() ); - $this->assertEquals( 'mwstore://local-backend/test-public/archive/!', $this->file_hl0->getArchivePath( '!' ) ); - $this->assertEquals( 'mwstore://local-backend/test-public/archive/a/a2/!', $this->file_hl2->getArchivePath( '!' ) ); - } - - function testGetThumbPath() { - $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!', $this->file_hl0->getThumbPath() ); - $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!', $this->file_hl2->getThumbPath() ); - $this->assertEquals( 'mwstore://local-backend/test-thumb/Test!/x', $this->file_hl0->getThumbPath( 'x' ) ); - $this->assertEquals( 'mwstore://local-backend/test-thumb/a/a2/Test!/x', $this->file_hl2->getThumbPath( 'x' ) ); - } - - function testGetArchiveUrl() { - $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() ); - $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() ); - $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) ); - $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) ); - } - - function testGetThumbUrl() { - $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() ); - $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() ); - $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) ); - $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) ); - } - - function testGetArchiveVirtualUrl() { - $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/public/archive/a/a2', $this->file_hl2->getArchiveVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/public/archive/%21', $this->file_hl0->getArchiveVirtualUrl( '!' ) ); - $this->assertEquals( 'mwrepo://test/public/archive/a/a2/%21', $this->file_hl2->getArchiveVirtualUrl( '!' ) ); - } - - function testGetThumbVirtualUrl() { - $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/thumb/Test%21/%21', $this->file_hl0->getThumbVirtualUrl( '!' ) ); - $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21/%21', $this->file_hl2->getThumbVirtualUrl( '!' ) ); - } - - function testGetUrl() { - $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); - $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); - } - - function testWfLocalFile() { - $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" ); - $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' ); - } -} - - diff --git a/tests/phpunit/includes/LocalisationCacheTest.php b/tests/phpunit/includes/LocalisationCacheTest.php deleted file mode 100644 index 356db87c..00000000 --- a/tests/phpunit/includes/LocalisationCacheTest.php +++ /dev/null @@ -1,31 +0,0 @@ -assertEquals( - $cache->getItem( 'ru', 'pluralRules' ), - $cache->getItem( 'os', 'pluralRules' ), - 'os plural rules (undefined) fallback to ru (defined)' - ); - - $this->assertEquals( - $cache->getItem( 'ru', 'compiledPluralRules' ), - $cache->getItem( 'os', 'compiledPluralRules' ), - 'os compiled plural rules (undefined) fallback to ru (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'pluralRules' ), - $cache->getItem( 'de', 'pluralRules' ), - 'ksh plural rules (defined) dont fallback to de (defined)' - ); - - $this->assertNotEquals( - $cache->getItem( 'ksh', 'compiledPluralRules' ), - $cache->getItem( 'de', 'compiledPluralRules' ), - 'ksh compiled plural rules (defined) dont fallback to de (defined)' - ); - } -} diff --git a/tests/phpunit/includes/MWFunctionTest.php b/tests/phpunit/includes/MWFunctionTest.php deleted file mode 100644 index ed5e7602..00000000 --- a/tests/phpunit/includes/MWFunctionTest.php +++ /dev/null @@ -1,86 +0,0 @@ -assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ) ), - MWFunction::call( 'MWFunctionTest::someMethod' ) - ); - $this->assertEquals( - call_user_func( array( 'MWFunctionTest', 'someMethod' ), 'foo', 'bar', 'baz' ), - MWFunction::call( 'MWFunctionTest::someMethod', 'foo', 'bar', 'baz' ) - ); - - - - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array() ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array() ) - ); - $this->assertEquals( - call_user_func_array( array( 'MWFunctionTest', 'someMethod' ), array( 'foo', 'bar', 'baz' ) ), - MWFunction::callArray( 'MWFunctionTest::someMethod', array( 'foo', 'bar', 'baz' ) ) - ); - - } - - function testNewObjFunction() { - - $arg1 = 'Foo'; - $arg2 = 'Bar'; - $arg3 = array( 'Baz' ); - $arg4 = new ExampleObject; - - $args = array( $arg1, $arg2, $arg3, $arg4 ); - - $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 ); - - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args )->args, - $newObject->args - ); - - $this->assertEquals( - MWFunction::newObj( 'MWBlankClass', $args, true )->args, - $newObject->args, - 'Works even with PHP version < 5.1.3' - ); - - } - - /** - * @expectedException MWException - */ - function testCallingParentFails() { - - MWFunction::call( 'parent::foo' ); - } - - /** - * @expectedException MWException - */ - function testCallingSelfFails() { - - MWFunction::call( 'self::foo' ); - } - - public static function someMethod() { - return func_get_args(); - } - -} - -class MWBlankClass { - - public $args = array(); - - function __construct( $arg1, $arg2, $arg3, $arg4 ) { - $this->args = array( $arg1, $arg2, $arg3, $arg4 ); - } - -} - -class ExampleObject { -} diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php deleted file mode 100644 index 3b05d675..00000000 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ /dev/null @@ -1,628 +0,0 @@ -assertFalse( MWNamespace::isMovable( NS_CATEGORY ) ); - # @todo FIXME: Write more tests!! - } - - /** - * Please make sure to change testIsTalk() if you change the assertions below - */ - public function testIsSubject() { - // Special namespaces - $this->assertIsSubject( NS_MEDIA ); - $this->assertIsSubject( NS_SPECIAL ); - - // Subject pages - $this->assertIsSubject( NS_MAIN ); - $this->assertIsSubject( NS_USER ); - $this->assertIsSubject( 100 ); # user defined - - // Talk pages - $this->assertIsNotSubject( NS_TALK ); - $this->assertIsNotSubject( NS_USER_TALK ); - $this->assertIsNotSubject( 101 ); # user defined - } - - /** - * Reverse of testIsSubject(). - * Please update testIsSubject() if you change assertions below - */ - public function testIsTalk() { - // Special namespaces - $this->assertIsNotTalk( NS_MEDIA ); - $this->assertIsNotTalk( NS_SPECIAL ); - - // Subject pages - $this->assertIsNotTalk( NS_MAIN ); - $this->assertIsNotTalk( NS_USER ); - $this->assertIsNotTalk( 100 ); # user defined - - // Talk pages - $this->assertIsTalk( NS_TALK ); - $this->assertIsTalk( NS_USER_TALK ); - $this->assertIsTalk( 101 ); # user defined - } - - /** - */ - public function testGetSubject() { - // Special namespaces are their own subjects - $this->assertEquals( NS_MEDIA, MWNamespace::getSubject( NS_MEDIA ) ); - $this->assertEquals( NS_SPECIAL, MWNamespace::getSubject( NS_SPECIAL ) ); - - $this->assertEquals( NS_MAIN, MWNamespace::getSubject( NS_TALK ) ); - $this->assertEquals( NS_USER, MWNamespace::getSubject( NS_USER_TALK ) ); - } - - /** - * Regular getTalk() calls - * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetTalkExceptions() - */ - public function testGetTalk() { - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_MAIN ) ); - $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_TALK ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER ) ); - $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER_TALK ) ); - } - - /** - * Exceptions with getTalk() - * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getTalk( NS_MEDIA ) ); - } - - /** - * Exceptions with getTalk() - * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them. - * @expectedException MWException - */ - public function testGetTalkExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getTalk( NS_SPECIAL ) ); - } - - /** - * Regular getAssociated() calls - * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in - * the function testGetAssociatedExceptions() - */ - public function testGetAssociated() { - $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); - $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - - } - - ### Exceptions with getAssociated() - ### NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises - ### an exception for them. - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsMedia() { - $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) ); - } - - /** - * @expectedException MWException - */ - public function testGetAssociatedExceptionsForNsSpecial() { - $this->assertNull( MWNamespace::getAssociated( NS_SPECIAL ) ); - } - - /** - * @todo Implement testExists(). - */ -/* - public function testExists() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } -*/ - - /** - * Test MWNamespace::equals - * Note if we add a namespace registration system with keys like 'MAIN' - * we should add tests here for equivilance on things like 'MAIN' == 0 - * and 'MAIN' == NS_MAIN. - */ - public function testEquals() { - $this->assertTrue( MWNamespace::equals( NS_MAIN, NS_MAIN ) ); - $this->assertTrue( MWNamespace::equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN' - $this->assertTrue( MWNamespace::equals( NS_USER, NS_USER ) ); - $this->assertTrue( MWNamespace::equals( NS_USER, 2 ) ); - $this->assertTrue( MWNamespace::equals( NS_USER_TALK, NS_USER_TALK ) ); - $this->assertTrue( MWNamespace::equals( NS_SPECIAL, NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::equals( NS_MAIN, NS_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_USER, NS_USER_TALK ) ); - $this->assertFalse( MWNamespace::equals( NS_PROJECT, NS_TEMPLATE ) ); - } - - /** - * Test MWNamespace::subjectEquals - */ - public function testSubjectEquals() { - $this->assertSameSubject( NS_MAIN, NS_MAIN ); - $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN' - $this->assertSameSubject( NS_USER, NS_USER ); - $this->assertSameSubject( NS_USER, 2 ); - $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK ); - $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL ); - $this->assertSameSubject( NS_MAIN, NS_TALK ); - $this->assertSameSubject( NS_USER, NS_USER_TALK ); - - $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE ); - $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN ); - } - - public function testSpecialAndMediaAreDifferentSubjects() { - $this->assertDifferentSubject( - NS_MEDIA, NS_SPECIAL, - "NS_MEDIA and NS_SPECIAL are different subject namespaces" - ); - $this->assertDifferentSubject( - NS_SPECIAL, NS_MEDIA, - "NS_SPECIAL and NS_MEDIA are different subject namespaces" - ); - - } - - /** - * @todo Implement testGetCanonicalNamespaces(). - */ -/* - public function testGetCanonicalNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } -*/ - /** - * @todo Implement testGetCanonicalName(). - */ -/* - public function testGetCanonicalName() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } -*/ - /** - * @todo Implement testGetCanonicalIndex(). - */ -/* - public function testGetCanonicalIndex() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } -*/ - /** - * @todo Implement testGetValidNamespaces(). - */ -/* - public function testGetValidNamespaces() { - // Remove the following lines when you implement this test. - $this->markTestIncomplete( - 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.' - ); - } -*/ - /** - */ - public function testCanTalk() { - $this->assertCanNotTalk( NS_MEDIA ); - $this->assertCanNotTalk( NS_SPECIAL ); - - $this->assertCanTalk( NS_MAIN ); - $this->assertCanTalk( NS_TALK ); - $this->assertCanTalk( NS_USER ); - $this->assertCanTalk( NS_USER_TALK ); - - // User defined namespaces - $this->assertCanTalk( 100 ); - $this->assertCanTalk( 101 ); - } - - /** - */ - public function testIsContent() { - // NS_MAIN is a content namespace per DefaultSettings.php - // and per function definition. - $this->assertIsContent( NS_MAIN ); - - global $wgContentNamespaces; - - $saved = $wgContentNamespaces; - - $wgContentNamespaces[] = NS_MAIN; - $this->assertIsContent( NS_MAIN ); - - // Other namespaces which are not expected to be content - if ( isset( $wgContentNamespaces[NS_MEDIA] ) ) { - unset( $wgContentNamespaces[NS_MEDIA] ); - } - $this->assertIsNotContent( NS_MEDIA ); - - if ( isset( $wgContentNamespaces[NS_SPECIAL] ) ) { - unset( $wgContentNamespaces[NS_SPECIAL] ); - } - $this->assertIsNotContent( NS_SPECIAL ); - - if ( isset( $wgContentNamespaces[NS_TALK] ) ) { - unset( $wgContentNamespaces[NS_TALK] ); - } - $this->assertIsNotContent( NS_TALK ); - - if ( isset( $wgContentNamespaces[NS_USER] ) ) { - unset( $wgContentNamespaces[NS_USER] ); - } - $this->assertIsNotContent( NS_USER ); - - if ( isset( $wgContentNamespaces[NS_CATEGORY] ) ) { - unset( $wgContentNamespaces[NS_CATEGORY] ); - } - $this->assertIsNotContent( NS_CATEGORY ); - - if ( isset( $wgContentNamespaces[100] ) ) { - unset( $wgContentNamespaces[100] ); - } - $this->assertIsNotContent( 100 ); - - $wgContentNamespaces = $saved; - } - - /** - * Similar to testIsContent() but alters the $wgContentNamespaces - * global variable. - */ - public function testIsContentWithAdditionsInWgContentNamespaces() { - // NS_MAIN is a content namespace per DefaultSettings.php - // and per function definition. - $this->assertIsContent( NS_MAIN ); - - // Tests that user defined namespace #252 is not content: - $this->assertIsNotContent( 252 ); - - # @todo FIXME: Is global saving really required for PHPUnit? - // Bless namespace # 252 as a content namespace - global $wgContentNamespaces; - $savedGlobal = $wgContentNamespaces; - $wgContentNamespaces[] = 252; - $this->assertIsContent( 252 ); - - // Makes sure NS_MAIN was not impacted - $this->assertIsContent( NS_MAIN ); - - // Restore global - $wgContentNamespaces = $savedGlobal; - - // Verify namespaces after global restauration - $this->assertIsContent( NS_MAIN ); - $this->assertIsNotContent( 252 ); - } - - public function testIsWatchable() { - // Specials namespaces are not watchable - $this->assertIsNotWatchable( NS_MEDIA ); - $this->assertIsNotWatchable( NS_SPECIAL ); - - // Core defined namespaces are watchables - $this->assertIsWatchable( NS_MAIN ); - $this->assertIsWatchable( NS_TALK ); - - // Additional, user defined namespaces are watchables - $this->assertIsWatchable( 100 ); - $this->assertIsWatchable( 101 ); - } - - public function testHasSubpages() { - // Special namespaces: - $this->assertHasNotSubpages( NS_MEDIA ); - $this->assertHasNotSubpages( NS_SPECIAL ); - - // namespaces without subpages - # save up global - global $wgNamespacesWithSubpages; - $saved = null; - if( array_key_exists( NS_MAIN, $wgNamespacesWithSubpages ) ) { - $saved = $wgNamespacesWithSubpages[NS_MAIN]; - unset( $wgNamespacesWithSubpages[NS_MAIN] ); - } - - $this->assertHasNotSubpages( NS_MAIN ); - - $wgNamespacesWithSubpages[NS_MAIN] = true; - $this->assertHasSubpages( NS_MAIN ); - $wgNamespacesWithSubpages[NS_MAIN] = false; - $this->assertHasNotSubpages( NS_MAIN ); - - # restore global - if( $saved !== null ) { - $wgNamespacesWithSubpages[NS_MAIN] = $saved; - } - - // Some namespaces with subpages - $this->assertHasSubpages( NS_TALK ); - $this->assertHasSubpages( NS_USER ); - $this->assertHasSubpages( NS_USER_TALK ); - } - - /** - */ - public function testGetContentNamespaces() { - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getcontentNamespaces(), - '$wgContentNamespaces is an array with only NS_MAIN by default' - ); - - global $wgContentNamespaces; - - $saved = $wgContentNamespaces; - # test !is_array( $wgcontentNamespaces ) - $wgContentNamespaces = ''; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); - $wgContentNamespaces = false; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); - $wgContentNamespaces = null; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); - $wgContentNamespaces = 5; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); - - # test $wgContentNamespaces === array() - $wgContentNamespaces = array(); - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); - - # test !in_array( NS_MAIN, $wgContentNamespaces ) - $wgContentNamespaces = array( NS_USER, NS_CATEGORY ); - $this->assertEquals( - array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces(), - 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' - ); - - # test other cases, return $wgcontentNamespaces as is - $wgContentNamespaces = array( NS_MAIN ); - $this->assertEquals( - array( NS_MAIN ), - MWNamespace::getcontentNamespaces() - ); - - $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); - $this->assertEquals( - array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces() - ); - - $wgContentNamespaces = $saved; - } - - /** - */ - public function testGetSubjectNamespaces() { - $subjectsNS = MWNamespace::getSubjectNamespaces(); - $this->assertContains( NS_MAIN, $subjectsNS, - "Talk namespaces should have NS_MAIN" ); - $this->assertNotContains( NS_TALK, $subjectsNS, - "Talk namespaces should have NS_TALK" ); - - $this->assertNotContains( NS_MEDIA, $subjectsNS, - "Talk namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $subjectsNS, - "Talk namespaces should not have NS_SPECIAL" ); - } - - /** - */ - public function testGetTalkNamespaces() { - $talkNS = MWNamespace::getTalkNamespaces(); - $this->assertContains( NS_TALK, $talkNS, - "Subject namespaces should have NS_TALK" ); - $this->assertNotContains( NS_MAIN, $talkNS, - "Subject namespaces should not have NS_MAIN" ); - - $this->assertNotContains( NS_MEDIA, $talkNS, - "Subject namespaces should not have NS_MEDIA" ); - $this->assertNotContains( NS_SPECIAL, $talkNS, - "Subject namespaces should not have NS_SPECIAL" ); - } - - /** - * Some namespaces are always capitalized per code definition - * in MWNamespace::$alwaysCapitalizedNamespaces - */ - public function testIsCapitalizedHardcodedAssertions() { - // NS_MEDIA and NS_FILE are treated the same - $this->assertEquals( - MWNamespace::isCapitalized( NS_MEDIA ), - MWNamespace::isCapitalized( NS_FILE ), - 'NS_MEDIA and NS_FILE have same capitalization rendering' - ); - - // Boths are capitalized by default - $this->assertIsCapitalized( NS_MEDIA ); - $this->assertIsCapitalized( NS_FILE ); - - // Always capitalized namespaces - // @see MWNamespace::$alwaysCapitalizedNamespaces - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - } - - /** - * Follows up for testIsCapitalizedHardcodedAssertions() but alter the - * global $wgCapitalLink setting to have extended coverage. - * - * MWNamespace::isCapitalized() rely on two global settings: - * $wgCapitalLinkOverrides = array(); by default - * $wgCapitalLinks = true; by default - * This function test $wgCapitalLinks - * - * Global setting correctness is tested against the NS_PROJECT and - * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials - */ - public function testIsCapitalizedWithWgCapitalLinks() { - global $wgCapitalLinks; - // Save the global to easily reset to MediaWiki default settings - $savedGlobal = $wgCapitalLinks; - - $wgCapitalLinks = true; - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - - $wgCapitalLinks = false; - // hardcoded namespaces (see above function) are still capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - // setting is correctly applied - $this->assertIsNotCapitalized( NS_PROJECT ); - $this->assertIsNotCapitalized( NS_PROJECT_TALK ); - - // reset global state: - $wgCapitalLinks = $savedGlobal; - } - - /** - * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now - * testing the $wgCapitalLinkOverrides global. - * - * @todo split groups of assertions in autonomous testing functions - */ - public function testIsCapitalizedWithWgCapitalLinkOverrides() { - global $wgCapitalLinkOverrides; - // Save the global to easily reset to MediaWiki default settings - $savedGlobal = $wgCapitalLinkOverrides; - - // Test default settings - $this->assertIsCapitalized( NS_PROJECT ); - $this->assertIsCapitalized( NS_PROJECT_TALK ); - // hardcoded namespaces (see above function) are capitalized: - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - // Hardcoded namespaces remains capitalized - $wgCapitalLinkOverrides[NS_SPECIAL] = false; - $wgCapitalLinkOverrides[NS_USER] = false; - $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false; - $this->assertIsCapitalized( NS_SPECIAL ); - $this->assertIsCapitalized( NS_USER ); - $this->assertIsCapitalized( NS_MEDIAWIKI ); - - $wgCapitalLinkOverrides = $savedGlobal; - $wgCapitalLinkOverrides[NS_PROJECT] = false; - $this->assertIsNotCapitalized( NS_PROJECT ); - $wgCapitalLinkOverrides[NS_PROJECT] = true ; - $this->assertIsCapitalized( NS_PROJECT ); - unset( $wgCapitalLinkOverrides[NS_PROJECT] ); - $this->assertIsCapitalized( NS_PROJECT ); - - // reset global state: - $wgCapitalLinkOverrides = $savedGlobal; - } - - public function testHasGenderDistinction() { - // Namespaces with gender distinctions - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) ); - $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) ); - - // Other ones, "genderless" - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) ); - $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) ); - - } - - public function testIsNonincludable() { - global $wgNonincludableNamespaces; - $wgNonincludableNamespaces = array( NS_USER ); - - $this->assertTrue( MWNamespace::isNonincludable( NS_USER ) ); - - $this->assertFalse( MWNamespace::isNonincludable( NS_TEMPLATE ) ); - } - - ####### HELPERS ########################################################### - function __call( $method, $args ) { - // Call the real method if it exists - if( method_exists($this, $method ) ) { - return $this->$method( $args ); - } - - if( preg_match( '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/', $method, $m ) ) { - # Interprets arguments: - $ns = $args[0]; - $msg = isset($args[1]) ? $args[1] : " dummy message"; - - # Forge the namespace constant name: - if( $ns === 0 ) { - $ns_name = "NS_MAIN"; - } else { - $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) ); - } - # ... and the MWNamespace method name - $nsMethod = strtolower( $m[1] ) . $m[3]; - - $expect = ($m[2] === ''); - $expect_name = $expect ? 'TRUE' : 'FALSE'; - - return $this->assertEquals( $expect, - MWNamespace::$nsMethod( $ns, $msg ), - "MWNamespace::$nsMethod( $ns_name ) should returns $expect_name" - ); - } - - throw new Exception( __METHOD__ . " could not find a method named $method\n" ); - } - - function assertSameSubject( $ns1, $ns2, $msg = '' ) { - $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } - function assertDifferentSubject( $ns1, $ns2, $msg = '' ) { - $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) ); - } -} - diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php deleted file mode 100644 index 20181fd4..00000000 --- a/tests/phpunit/includes/MessageTest.php +++ /dev/null @@ -1,64 +0,0 @@ -assertTrue( wfMessage( 'mainpage' )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->params( array() )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); - } - - function testKey() { - $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); - $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() ); - $this->assertEquals( '', wfMessage( 'i-dont-exist-evar' )->plain() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); - } - - function testInLanguage() { - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() ); - $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'en' ) )->text() ); - $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'ru' ) )->text() ); - } - - function testMessageParams() { - $this->assertEquals( 'Return to $1.', wfMessage( 'returnto' )->text() ); - $this->assertEquals( 'Return to $1.', wfMessage( 'returnto', array() )->text() ); - $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', 'foo', 'bar' )->text() ); - $this->assertEquals( 'You have foo (bar).', wfMessage( 'youhavenewmessages', array( 'foo', 'bar' ) )->text() ); - } - - function testMessageParamSubstitution() { - $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses', 'Заглавная страница' )->plain() ); - $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses', 'Заглавная страница $1' )->plain() ); - $this->assertEquals( '(Заглавная страница)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница' )->plain() ); - $this->assertEquals( '(Заглавная страница $1)', wfMessage( 'parentheses' )->rawParams( 'Заглавная страница $1' )->plain() ); - } - - function testInContentLanguage() { - global $wgLang, $wgForceUIMsgAsContentMsg; - $oldLang = $wgLang; - $wgLang = Language::factory( 'fr' ); - - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg disabled' ); - $wgForceUIMsgAsContentMsg['testInContentLanguage'] = 'mainpage'; - $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); - - /* Restore globals */ - $wgLang = $oldLang; - unset( $wgForceUIMsgAsContentMsg['testInContentLanguage'] ); - } - - /** - * @expectedException MWException - */ - function testInLanguageThrows() { - wfMessage( 'foo' )->inLanguage( 123 ); - } -} diff --git a/tests/phpunit/includes/ParserOptionsTest.php b/tests/phpunit/includes/ParserOptionsTest.php deleted file mode 100644 index 59c955fe..00000000 --- a/tests/phpunit/includes/ParserOptionsTest.php +++ /dev/null @@ -1,35 +0,0 @@ -popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang ); - $this->pcache = ParserCache::singleton(); - } - - function tearDown() { - parent::tearDown(); - } - - /** - * ParserOptions::optionsHash was not giving consistent results when $wgUseDynamicDates was set - * @group Database - */ - function testGetParserCacheKeyWithDynamicDates() { - global $wgUseDynamicDates; - $wgUseDynamicDates = true; - - $title = Title::newFromText( "Some test article" ); - $page = WikiPage::factory( $title ); - - $pcacheKeyBefore = $this->pcache->getKey( $page, $this->popts ); - $this->assertNotNull( $this->popts->getDateFormat() ); - $pcacheKeyAfter = $this->pcache->getKey( $page, $this->popts ); - $this->assertEquals( $pcacheKeyBefore, $pcacheKeyAfter ); - } -} diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php deleted file mode 100644 index f6274584..00000000 --- a/tests/phpunit/includes/PathRouterTest.php +++ /dev/null @@ -1,254 +0,0 @@ -add("/wiki/$1"); - $this->basicRouter = $router; - } - - /** - * Test basic path parsing - */ - public function testBasic() { - $matches = $this->basicRouter->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test loose path auto-$1 - */ - public function testLoose() { - $router = new PathRouter; - $router->add("/"); # Should be the same as "/$1" - $matches = $router->parse( "/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add("/wiki"); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add("/wiki/"); # Should be the same as /wiki/$1 - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test to ensure that path is based on specifity, not order - */ - public function testOrder() { - $router = new PathRouter; - $router->add("/$1"); - $router->add("/a/$1"); - $router->add("/b/$1"); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - - $router = new PathRouter; - $router->add("/b/$1"); - $router->add("/a/$1"); - $router->add("/$1"); - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo" ) ); - } - - /** - * Test the handling of key based arrays with a url parameter - */ - public function testKeyParameter() { - $router = new PathRouter; - $router->add( array( 'edit' => "/edit/$1" ), array( 'action' => '$key' ) ); - $matches = $router->parse( "/edit/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'action' => 'edit' ) ); - } - - /** - * Test the handling of $2 inside paths - */ - public function testAdditionalParameter() { - // Basic $2 - $router = new PathRouter; - $router->add( '/$2/$1', array( 'test' => '$2' ) ); - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'asdf' ) ); - } - - /** - * Test additional restricted value parameter - */ - public function testRestrictedValue() { - $router = new PathRouter; - $router->add( '/$2/$1', - array( 'test' => '$2' ), - array( '$2' => array( 'a', 'b' ) ) - ); - $router->add( '/$2/$1', - array( 'test2' => '$2' ), - array( '$2' => 'c' ) - ); - $router->add( '/$1' ); - - $matches = $router->parse( "/asdf/Foo" ); - $this->assertEquals( $matches, array( 'title' => "asdf/Foo" ) ); - - $matches = $router->parse( "/a/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'a' ) ); - - $matches = $router->parse( "/c/Foo" ); - $this->assertEquals( $matches, array( 'title' => "Foo", 'test2' => 'c' ) ); - } - - public function callbackForTest( &$matches, $data ) { - $matches['x'] = $data['$1']; - $matches['foo'] = $data['foo']; - } - - public function testCallback() { - $router = new PathRouter; - $router->add( "/$1", - array( 'a' => 'b', 'data:foo' => 'bar' ), - array( 'callback' => array( $this, 'callbackForTest' ) ) - ); - $matches = $router->parse( '/Foo' ); - $this->assertEquals( $matches, array( - 'title' => "Foo", - 'x' => 'Foo', - 'a' => 'b', - 'foo' => 'bar' - ) ); - } - - /** - * Test to ensure that matches are not made if a parameter expects nonexistent input - */ - public function testFail() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => "$1$2" ) ); - $matches = $router->parse( "/wiki/A" ); - $this->assertEquals( array(), $matches ); - } - - /** - * Test to ensure weight of paths is handled correctly - */ - public function testWeight() { - $router = new PathRouter; - $router->addStrict( "/Bar", array( 'ping' => 'pong' ) ); - $router->add( "/asdf-$1", array( 'title' => 'qwerty-$1' ) ); - $router->add( "/$1" ); - $router->add( "/qwerty-$1", array( 'title' => 'asdf-$1' ) ); - $router->addStrict( "/Baz", array( 'marco' => 'polo' ) ); - $router->add( "/a/$1" ); - $router->add( "/asdf/$1" ); - $router->add( "/$2/$1", array( 'unrestricted' => '$2' ) ); - $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) ); - $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) ); - - foreach( array( - "/Foo" => array( 'title' => "Foo" ), - "/Bar" => array( 'ping' => 'pong' ), - "/Baz" => array( 'marco' => 'polo' ), - "/asdf-foo" => array( 'title' => "qwerty-foo" ), - "/qwerty-bar" => array( 'title' => "asdf-bar" ), - "/a/Foo" => array( 'title' => "Foo" ), - "/asdf/Foo" => array( 'title' => "Foo" ), - "/qwerty/Foo" => array( 'title' => "Foo", 'qwerty' => 'qwerty' ), - "/baz/Foo" => array( 'title' => "Foo", 'unrestricted' => 'baz' ), - "/y/Foo" => array( 'title' => "Foo", 'restricted-to-y' => 'y' ), - ) as $path => $result ) { - $this->assertEquals( $router->parse( $path ), $result ); - } - } - - /** - * Make sure the router handles titles like Special:Recentchanges correctly - */ - public function testSpecial() { - $matches = $this->basicRouter->parse( "/wiki/Special:Recentchanges" ); - $this->assertEquals( $matches, array( 'title' => "Special:Recentchanges" ) ); - } - - /** - * Make sure the router decodes urlencoding properly - */ - public function testUrlencoding() { - $matches = $this->basicRouter->parse( "/wiki/Title_With%20Space" ); - $this->assertEquals( $matches, array( 'title' => "Title_With Space" ) ); - } - - public function dataRegexpChars() { - return array( - array( "$" ), - array( "$1" ), - array( "\\" ), - array( "\\$1" ), - ); - } - - /** - * Make sure the router doesn't break on special characters like $ used in regexp replacements - * @dataProvider dataRegexpChars - */ - public function testRegexpChars( $char ) { - $matches = $this->basicRouter->parse( "/wiki/$char" ); - $this->assertEquals( $matches, array( 'title' => "$char" ) ); - } - - /** - * Make sure the router handles characters like +&() properly - */ - public function testCharacters() { - $matches = $this->basicRouter->parse( "/wiki/Plus+And&Dollar\\Stuff();[]{}*" ); - $this->assertEquals( $matches, array( 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ) ); - } - - /** - * Make sure the router handles unicode characters correctly - * @depends testSpecial - * @depends testUrlencoding - * @depends testCharacters - */ - public function testUnicode() { - $matches = $this->basicRouter->parse( "/wiki/Spécial:Modifications_récentes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - - $matches = $this->basicRouter->parse( "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes" ); - $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) ); - } - - /** - * Ensure the router doesn't choke on long paths. - */ - public function testLength() { - $matches = $this->basicRouter->parse( "/wiki/Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ); - $this->assertEquals( $matches, array( 'title' => "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ) ); - } - - - /** - * Ensure that the php passed site of parameter values are not urldecoded - */ - public function testPatternUrlencoding() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => '%20:$1' ) ); - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => '%20:Foo' ) ); - } - - /** - * Ensure that raw parameter values do not have any variable replacements or urldecoding - */ - public function testRawParamValue() { - $router = new PathRouter; - $router->add( "/wiki/$1", array( 'title' => array( 'value' => 'bar%20$1' ) ) ); - $matches = $router->parse( "/wiki/Foo" ); - $this->assertEquals( $matches, array( 'title' => 'bar%20$1' ) ); - } - -} diff --git a/tests/phpunit/includes/PreferencesTest.php b/tests/phpunit/includes/PreferencesTest.php deleted file mode 100644 index 0e123177..00000000 --- a/tests/phpunit/includes/PreferencesTest.php +++ /dev/null @@ -1,75 +0,0 @@ -prefUsers['noemail'] = new User; - - $this->prefUsers['notauth'] = new User; - $this->prefUsers['notauth'] - ->setEmail( 'noauth@example.org' ); - - $this->prefUsers['auth'] = new User; - $this->prefUsers['auth'] - ->setEmail( 'noauth@example.org' ); - $this->prefUsers['auth'] - ->setEmailAuthenticationTimestamp( 1330946623 ); - - $this->context = new RequestContext; - $this->context->setTitle( Title::newFromText('PreferencesTest') ); - - //some tests depends on email setting - $wgEnableEmail = true; - } - - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - function testEmailFieldsWhenUserHasNoEmail() { - $prefs = $this->prefsFor( 'noemail' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-none', $prefs['emailaddress']['cssclass'] ); - } - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - function testEmailFieldsWhenUserEmailNotAuthenticated() { - $prefs = $this->prefsFor( 'notauth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-not-authenticated', $prefs['emailaddress']['cssclass'] ); - } - /** - * Placeholder to verify bug 34302 - * @covers Preferences::profilePreferences - */ - function testEmailFieldsWhenUserEmailIsAuthenticated() { - $prefs = $this->prefsFor( 'auth' ); - $this->assertArrayHasKey( 'cssclass', - $prefs['emailaddress'] - ); - $this->assertEquals( 'mw-email-authenticated', $prefs['emailaddress']['cssclass'] ); - } - - /** Helper */ - function prefsFor( $user_key ) { - $preferences = array(); - Preferences::profilePreferences( - $this->prefUsers[$user_key] - , $this->context - , $preferences - ); - return $preferences; - } -} diff --git a/tests/phpunit/includes/Providers.php b/tests/phpunit/includes/Providers.php deleted file mode 100644 index f451f8a0..00000000 --- a/tests/phpunit/includes/Providers.php +++ /dev/null @@ -1,44 +0,0 @@ -title = Title::newFromText( 'SomeTitle' ); - $this->target = Title::newFromText( 'TestTarget' ); - $this->user = User::newFromName( 'UserName' ); - - $this->user_comment = ''; - $this->context = RequestContext::newExtraneousContext( $this->title ); - } - - /** - * The testIrcMsgForAction* tests are supposed to cover the hacky - * LogFormatter::getIRCActionText / bug 34508 - * - * Third parties bots listen to those messages. They are clever enough - * to fetch the i18n messages from the wiki and then analyze the IRC feed - * to reverse engineer the $1, $2 messages. - * One thing bots can not detect is when MediaWiki change the meaning of - * a message like what happened when we deployed 1.19. $1 became the user - * performing the action which broke basically all bots around. - * - * Should cover the following log actions (which are most commonly used by bots): - * - block/block - * - block/unblock - * - delete/delete - * - delete/restore - * - newusers/create - * - newusers/create2 - * - newusers/autocreate - * - move/move - * - move/move_redir - * - protect/protect - * - protect/modifyprotect - * - protect/unprotect - * - upload/upload - * - * As well as the following Auto Edit Summaries: - * - blank - * - replace - * - rollback - * - undo - */ - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeBlock() { - # block/block - $this->assertIRCComment( - $this->context->msg( 'blocklogentry', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'block', 'block', - array(), - $this->user_comment - ); - # block/unblock - $this->assertIRCComment( - $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'block', 'unblock', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeDelete() { - # delete/delete - $this->assertIRCComment( - $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'delete', 'delete', - array(), - $this->user_comment - ); - - # delete/restore - $this->assertIRCComment( - $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'delete', 'restore', - array(), - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeNewusers() { - $this->assertIRCComment( - 'New user account', - 'newusers', 'newusers', - array() - ); - $this->assertIRCComment( - 'New user account', - 'newusers', 'create', - array() - ); - $this->assertIRCComment( - 'created new account SomeTitle', - 'newusers', 'create2', - array() - ); - $this->assertIRCComment( - 'Account created automatically', - 'newusers', 'autocreate', - array() - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeMove() { - $move_params = array( - '4::target' => $this->target->getPrefixedText(), - '5::noredir' => 0, - ); - - # move/move - $this->assertIRCComment( - $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )->plain() . ': ' . $this->user_comment, - 'move', 'move', - $move_params, - $this->user_comment - ); - - # move/move_redir - $this->assertIRCComment( - $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )->plain() . ': ' . $this->user_comment, - 'move', 'move_redir', - $move_params, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypePatrol() { - # patrol/patrol - $this->assertIRCComment( - $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), - 'patrol', 'patrol', - array( - '4::curid' => '777', - '5::previd' => '666', - '6::auto' => 0, - ) - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeProtect() { - $protectParams = array( - '[edit=sysop] (indefinite) ‎[move=sysop] (indefinite)' - ); - - # protect/protect - $this->assertIRCComment( - $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )->plain() . ': ' . $this->user_comment, - 'protect', 'protect', - $protectParams, - $this->user_comment - ); - - # protect/unprotect - $this->assertIRCComment( - $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'protect', 'unprotect', - array(), - $this->user_comment - ); - - # protect/modify - $this->assertIRCComment( - $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )->plain() . ': ' . $this->user_comment, - 'protect', 'modify', - $protectParams, - $this->user_comment - ); - } - - /** - * @covers LogFormatter::getIRCActionText - */ - function testIrcMsgForLogTypeUpload() { - # upload/upload - $this->assertIRCComment( - $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'upload', 'upload', - array(), - $this->user_comment - ); - - # upload/overwrite - $this->assertIRCComment( - $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . ': ' . $this->user_comment, - 'upload', 'overwrite', - array(), - $this->user_comment - ); - } - - /** - * @todo: Emulate these edits somehow and extract - * raw edit summary from RecentChange object - * -- - - function testIrcMsgForBlankingAES() { - // $this->context->msg( 'autosumm-blank', .. ); - } - - function testIrcMsgForReplaceAES() { - // $this->context->msg( 'autosumm-replace', .. ); - } - - function testIrcMsgForRollbackAES() { - // $this->context->msg( 'revertpage', .. ); - } - - function testIrcMsgForUndoAES() { - // $this->context->msg( 'undo-summary', .. ); - } - - * -- - */ - - /** - * @param $expected String Expected IRC text without colors codes - * @param $type String Log type (move, delete, suppress, patrol ...) - * @param $action String A log type action - * @param $comment String (optional) A comment for the log action - * @param $msg String (optional) A message for PHPUnit :-) - */ - function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { - - $logEntry = new ManualLogEntry( $type, $action ); - $logEntry->setPerformer( $this->user ); - $logEntry->setTarget( $this->title ); - if ( $comment !== null ) { - $logEntry->setComment( $comment ); - } - $logEntry->setParameters( $params ); - - $formatter = LogFormatter::newFromEntry( $logEntry ); - $formatter->setContext( $this->context ); - - // Apply the same transformation as done in RecentChange::getIRCLine for rc_comment - $ircRcComment = RecentChange::cleanupForIRC( $formatter->getIRCActionComment() ); - - $this->assertEquals( - $expected, - $ircRcComment, - $msg - ); - } - -} diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php deleted file mode 100644 index ab704839..00000000 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ /dev/null @@ -1,91 +0,0 @@ -assertTrue( self::$resourceLoaderRegisterModulesHook ); - return $resourceLoader; - } - - /** - * @dataProvider provideValidModules - * @depends testCreatingNewResourceLoaderCallsRegistrationHook - * @covers ResourceLoader::register - * @covers ResourceLoader::getModule - */ - public function testRegisteredValidModulesAreAccessible( - $name, ResourceLoaderModule $module, ResourceLoader $resourceLoader - ) { - $resourceLoader->register( $name, $module ); - $this->assertEquals( $module, $resourceLoader->getModule( $name ) ); - } - - /** - * @dataProvider providePackedModules - */ - public function testMakePackedModulesString( $desc, $modules, $packed ) { - $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc ); - } - - /** - * @dataProvider providePackedModules - */ - public function testexpandModuleNames( $desc, $modules, $packed ) { - $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); - } - - public function providePackedModules() { - return array( - array( - 'Example from makePackedModulesString doc comment', - array( 'foo.bar', 'foo.baz', 'bar.baz', 'bar.quux' ), - 'foo.bar,baz|bar.baz,quux', - ), - array( - 'Example from expandModuleNames doc comment', - array( 'jquery.foo', 'jquery.bar', 'jquery.ui.baz', 'jquery.ui.quux' ), - 'jquery.foo,bar|jquery.ui.baz,quux', - ), - array( - 'Regression fixed in r88706 with dotless names', - array( 'foo', 'bar', 'baz' ), - 'foo,bar,baz', - ) - ); - } -} - -/* Stubs */ - -class ResourceLoaderTestModule extends ResourceLoaderModule { } - -/* Hooks */ -global $wgHooks; -$wgHooks['ResourceLoaderRegisterModules'][] = 'ResourceLoaderTest::resourceLoaderRegisterModules'; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php deleted file mode 100644 index 8a7facec..00000000 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ /dev/null @@ -1,408 +0,0 @@ -tablesUsed = array_merge( $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - public function setUp() { - if ( !$this->the_page ) { - $this->the_page = $this->createPage( 'RevisionStorageTest_the_page', "just a dummy page" ); - } - } - - protected function makeRevision( $props = null ) { - if ( $props === null ) $props = array(); - - if ( !isset( $props['content'] ) && !isset( $props['text'] ) ) $props['text'] = 'Lorem Ipsum'; - if ( !isset( $props['comment'] ) ) $props['comment'] = 'just a test'; - if ( !isset( $props['page'] ) ) $props['page'] = $this->the_page->getId(); - - $rev = new Revision( $props ); - - $dbw = wfgetDB( DB_MASTER ); - $rev->insertOn( $dbw ); - - return $rev; - } - - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) ) $page = Title::newFromText( $page ); - if ( $page instanceof Title ) $page = new WikiPage( $page ); - - if ( $page->exists() ) { - $page->doDeleteArticle( "done" ); - } - - $page->doEdit( $text, "testing", EDIT_NEW ); - - return $page; - } - - protected function assertRevEquals( Revision $orig, Revision $rev = null ) { - $this->assertNotNull( $rev, 'missing revision' ); - - $this->assertEquals( $orig->getId(), $rev->getId() ); - $this->assertEquals( $orig->getPage(), $rev->getPage() ); - $this->assertEquals( $orig->getTimestamp(), $rev->getTimestamp() ); - $this->assertEquals( $orig->getUser(), $rev->getUser() ); - $this->assertEquals( $orig->getSha1(), $rev->getSha1() ); - } - - /** - * @covers Revision::__construct - */ - public function testConstructFromRow() - { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = new Revision( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromRow - */ - public function testNewFromRow() - { - $orig = $this->makeRevision(); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'revision', '*', array( 'rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - - /** - * @covers Revision::newFromArchiveRow - */ - public function testNewFromArchiveRow() - { - $page = $this->createPage( 'RevisionStorageTest_testNewFromArchiveRow', 'Lorem Ipsum' ); - $orig = $page->getRevision(); - $page->doDeleteArticle( 'test Revision::newFromArchiveRow' ); - - $dbr = wfgetDB( DB_SLAVE ); - $res = $dbr->select( 'archive', '*', array( 'ar_rev_id' => $orig->getId() ) ); - $this->assertTrue( is_object( $res ), 'query failed' ); - - $row = $res->fetchObject(); - $res->free(); - - $rev = Revision::newFromArchiveRow( $row ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::newFromId - */ - public function testNewFromId() - { - $orig = $this->makeRevision(); - - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertRevEquals( $orig, $rev ); - } - - /** - * @covers Revision::fetchRevision - */ - public function testFetchRevision() - { - $page = $this->createPage( 'RevisionStorageTest_testFetchRevision', 'one' ); - $id1 = $page->getRevision()->getId(); - - $page->doEdit( 'two', 'second rev' ); - $id2 = $page->getRevision()->getId(); - - $res = Revision::fetchRevision( $page->getTitle() ); - - #note: order is unspecified - $rows = array(); - while ( ( $row = $res->fetchObject() ) ) { - $rows[ $row->rev_id ]= $row; - } - - $row = $res->fetchObject(); - $this->assertEquals( 1, count($rows), 'expected exactly one revision' ); - $this->assertArrayHasKey( $id2, $rows, 'missing revision with id ' . $id2 ); - } - - /** - * @covers Revision::selectFields - */ - public function testSelectFields() - { - $fields = Revision::selectFields(); - - $this->assertTrue( in_array( 'rev_id', $fields ), 'missing rev_id in list of fields'); - $this->assertTrue( in_array( 'rev_page', $fields ), 'missing rev_page in list of fields'); - $this->assertTrue( in_array( 'rev_timestamp', $fields ), 'missing rev_timestamp in list of fields'); - $this->assertTrue( in_array( 'rev_user', $fields ), 'missing rev_user in list of fields'); - } - - /** - * @covers Revision::getPage - */ - public function testGetPage() - { - $page = $this->the_page; - - $orig = $this->makeRevision( array( 'page' => $page->getId() ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( $page->getId(), $rev->getPage() ); - } - - /** - * @covers Revision::getText - */ - public function testGetText() - { - $orig = $this->makeRevision( array( 'text' => 'hello hello.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello.', $rev->getText() ); - } - - /** - * @covers Revision::revText - */ - public function testRevText() - { - $this->hideDeprecated( 'Revision::revText' ); - $orig = $this->makeRevision( array( 'text' => 'hello hello rev.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello rev.', $rev->revText() ); - } - - /** - * @covers Revision::getRawText - */ - public function testGetRawText() - { - $orig = $this->makeRevision( array( 'text' => 'hello hello raw.' ) ); - $rev = Revision::newFromId( $orig->getId() ); - - $this->assertEquals( 'hello hello raw.', $rev->getRawText() ); - } - /** - * @covers Revision::isCurrent - */ - public function testIsCurrent() - { - $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum' ); - $rev1 = $page->getRevision(); - - # @todo: find out if this should be true - # $this->assertTrue( $rev1->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertTrue( $rev1x->isCurrent() ); - - $page->doEdit( 'Bla bla', 'second rev' ); - $rev2 = $page->getRevision(); - - # @todo: find out if this should be true - # $this->assertTrue( $rev2->isCurrent() ); - - $rev1x = Revision::newFromId( $rev1->getId() ); - $this->assertFalse( $rev1x->isCurrent() ); - - $rev2x = Revision::newFromId( $rev2->getId() ); - $this->assertTrue( $rev2x->isCurrent() ); - } - - /** - * @covers Revision::getPrevious - */ - public function testGetPrevious() - { - $page = $this->createPage( 'RevisionStorageTest_testGetPrevious', 'Lorem Ipsum testGetPrevious' ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getPrevious() ); - - $page->doEdit( 'Bla bla', 'second rev testGetPrevious' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev2->getPrevious() ); - $this->assertEquals( $rev1->getId(), $rev2->getPrevious()->getId() ); - } - - /** - * @covers Revision::getNext - */ - public function testGetNext() - { - $page = $this->createPage( 'RevisionStorageTest_testGetNext', 'Lorem Ipsum testGetNext' ); - $rev1 = $page->getRevision(); - - $this->assertNull( $rev1->getNext() ); - - $page->doEdit( 'Bla bla', 'second rev testGetNext' ); - $rev2 = $page->getRevision(); - - $this->assertNotNull( $rev1->getNext() ); - $this->assertEquals( $rev2->getId(), $rev1->getNext()->getId() ); - } - - /** - * @covers Revision::newNullRevision - */ - public function testNewNullRevision() - { - $page = $this->createPage( 'RevisionStorageTest_testNewNullRevision', 'some testing text' ); - $orig = $page->getRevision(); - - $dbw = wfGetDB( DB_MASTER ); - $rev = Revision::newNullRevision( $dbw, $page->getId(), 'a null revision', false ); - - $this->assertNotEquals( $orig->getId(), $rev->getId(), 'new null revision shold have a different id from the original revision' ); - $this->assertEquals( $orig->getTextId(), $rev->getTextId(), 'new null revision shold have the same text id as the original revision' ); - $this->assertEquals( 'some testing text', $rev->getText() ); - } - - public function dataUserWasLastToEdit() { - return array( - array( #0 - 3, true, # actually the last edit - ), - array( #1 - 2, true, # not the current edit, but still by this user - ), - array( #2 - 1, false, # edit by another user - ), - array( #3 - 0, false, # first edit, by this user, but another user edited in the mean time - ), - ); - } - - /** - * @dataProvider dataUserWasLastToEdit - */ - public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = \User::newFromName( "RevisionStorageTest_userA" ); - $userB = \User::newFromName( "RevisionStorageTest_userB" ); - - if ( $userA->getId() === 0 ) { - $userA = \User::createNew( $userA->getName() ); - } - - if ( $userB->getId() === 0 ) { - $userB = \User::createNew( $userB->getName() ); - } - - $dbw = wfGetDB( DB_MASTER ); - $revisions = array(); - - // create revisions ----------------------------- - $page = WikiPage::factory( Title::newFromText( 'RevisionStorageTest_testUserWasLastToEdit' ) ); - - # zero - $revisions[0] = new Revision( array( - 'page' => $page->getId(), - 'timestamp' => '20120101000000', - 'user' => $userA->getId(), - 'text' => 'zero', - 'summary' => 'edit zero' - ) ); - $revisions[0]->insertOn( $dbw ); - - # one - $revisions[1] = new Revision( array( - 'page' => $page->getId(), - 'timestamp' => '20120101000100', - 'user' => $userA->getId(), - 'text' => 'one', - 'summary' => 'edit one' - ) ); - $revisions[1]->insertOn( $dbw ); - - # two - $revisions[2] = new Revision( array( - 'page' => $page->getId(), - 'timestamp' => '20120101000200', - 'user' => $userB->getId(), - 'text' => 'two', - 'summary' => 'edit two' - ) ); - $revisions[2]->insertOn( $dbw ); - - # three - $revisions[3] = new Revision( array( - 'page' => $page->getId(), - 'timestamp' => '20120101000300', - 'user' => $userA->getId(), - 'text' => 'three', - 'summary' => 'edit three' - ) ); - $revisions[3]->insertOn( $dbw ); - - # four - $revisions[4] = new Revision( array( - 'page' => $page->getId(), - 'timestamp' => '20120101000200', - 'user' => $userA->getId(), - 'text' => 'zero', - 'summary' => 'edit four' - ) ); - $revisions[4]->insertOn( $dbw ); - - // test it --------------------------------- - $since = $revisions[ $sinceIdx ]->getTimestamp(); - - $wasLast = Revision::userWasLastToEdit( $dbw, $page->getId(), $userA->getId(), $since ); - - $this->assertEquals( $expectedLast, $wasLast ); - } -} diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php deleted file mode 100644 index d7654db9..00000000 --- a/tests/phpunit/includes/RevisionTest.php +++ /dev/null @@ -1,125 +0,0 @@ - false, - 'wgCompressRevisions' => false, - ); - foreach ( $globalSet as $var => $data ) { - $this->saveGlobals[$var] = $GLOBALS[$var]; - $GLOBALS[$var] = $data; - } - } - - function tearDown() { - foreach ( $this->saveGlobals as $var => $data ) { - $GLOBALS[$var] = $data; - } - } - - function testGetRevisionText() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = 'This is a bunch of revision text.'; - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextGzip() { - if ( !function_exists( 'gzdeflate' ) ) { - $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' ); - } else { - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( 'This is a bunch of revision text.' ); - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - } - - function testGetRevisionTextUtf8Native() { - $row = new stdClass; - $row->old_flags = 'utf-8'; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8Legacy() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = "Wiki est l'\xe9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8NativeGzip() { - if ( !function_exists( 'gzdeflate' ) ) { - $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' ); - } else { - $row = new stdClass; - $row->old_flags = 'gzip,utf-8'; - $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - } - - function testGetRevisionTextUtf8LegacyGzip() { - if ( !function_exists( 'gzdeflate' ) ) { - $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' ); - } else { - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - } - - function testCompressRevisionTextUtf8() { - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should not contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - $row->old_text, "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - function testCompressRevisionTextUtf8Gzip() { - $GLOBALS['wgCompressRevisions'] = true; - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - gzinflate( $row->old_text ), "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } -} - - diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php deleted file mode 100644 index 59ba0a04..00000000 --- a/tests/phpunit/includes/SampleTest.php +++ /dev/null @@ -1,98 +0,0 @@ -assertEquals("Text", $title->__toString(), "Title creation"); - $this->assertEquals("Text", "Text", "Automatic string conversion"); - - $title = Title::newFromText("text", NS_MEDIA); - $this->assertEquals("Media:Text", $title->__toString(), "Title creation with namespace"); - - } - - /** - * If you want to run a the same test with a variety of data. use a data provider. - * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html - */ - public function provideTitles() { - return array( - array( 'Text', NS_MEDIA, 'Media:Text' ), - array( 'Text', null, 'Text' ), - array( 'text', null, 'Text' ), - array( 'Text', NS_USER, 'User:Text' ), - array( 'Photo.jpg', NS_FILE, 'File:Photo.jpg' ) - ); - } - - /** - * @dataProvider provideTitles - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider - */ - public function testCreateBasicListOfTitles($titleName, $ns, $text) { - $title = Title::newFromText($titleName, $ns); - $this->assertEquals($text, "$title", "see if '$titleName' matches '$text'"); - } - - public function testSetUpMainPageTitleForNextTest() { - $title = Title::newMainPage(); - $this->assertEquals("Main Page", "$title", "Test initial creation of a title"); - - return $title; - } - - /** - * Instead of putting a bunch of tests in a single test method, - * you should put only one or two tests in each test method. This - * way, the test method names can remain descriptive. - * - * If you want to make tests depend on data created in another - * method, you can create dependencies feed whatever you return - * from the dependant method (e.g. testInitialCreation in this - * example) as arguments to the next method (e.g. $title in - * testTitleDepends is whatever testInitialCreatiion returned.) - */ - /** - * @depends testSetUpMainPageTitleForNextTest - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.depends - */ - public function testCheckMainPageTitleIsConsideredLocal( $title ) { - $this->assertTrue( $title->isLocal() ); - } - - /** - * @expectedException MWException object - * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException - */ - function testTitleObjectFromObject() { - $title = Title::newFromText( Title::newFromText( "test" ) ); - $this->assertEquals( "Test", $title->isLocal() ); - } -} - diff --git a/tests/phpunit/includes/SanitizerTest.php b/tests/phpunit/includes/SanitizerTest.php deleted file mode 100644 index 66af2581..00000000 --- a/tests/phpunit/includes/SanitizerTest.php +++ /dev/null @@ -1,162 +0,0 @@ -assertEquals( - "\xc3\xa9cole", - Sanitizer::decodeCharReferences( 'école' ), - 'decode named entities' - ); - } - - function testDecodeNumericEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode numeric entities' - ); - } - - function testDecodeMixedEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode mixed numeric/named entities' - ); - } - - function testDecodeMixedComplexEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", - Sanitizer::decodeCharReferences( - "Ĉio bonas dans l'école! (mais pas &#x108;io dans l'&eacute;cole)" - ), - 'decode mixed complex entities' - ); - } - - function testInvalidAmpersand() { - $this->assertEquals( - 'a & b', - Sanitizer::decodeCharReferences( 'a & b' ), - 'Invalid ampersand' - ); - } - - function testInvalidEntities() { - $this->assertEquals( - '&foo;', - Sanitizer::decodeCharReferences( '&foo;' ), - 'Invalid named entity' - ); - } - - function testInvalidNumberedEntities() { - $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); - } - - function testSelfClosingTag() { - $GLOBALS['wgUseTidy'] = false; - $this->assertEquals( - '
    Hello world
    ', - Sanitizer::removeHTMLtags( '
    Hello world
    ' ), - 'Self-closing closing div' - ); - } - - function testDecodeTagAttributes() { - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=bar' ), array( 'foo' => 'bar' ), 'Unquoted attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( ' foo = bar ' ), array( 'foo' => 'bar' ), 'Spaced attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo="bar"' ), array( 'foo' => 'bar' ), 'Double-quoted attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=\'bar\'' ), array( 'foo' => 'bar' ), 'Single-quoted attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=\'bar\' baz="foo"' ), array( 'foo' => 'bar', 'baz' => 'foo' ), 'Several attributes' ); - - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=\'bar\' baz="foo"' ), array( 'foo' => 'bar', 'baz' => 'foo' ), 'Several attributes' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=\'bar\' baz="foo"' ), array( 'foo' => 'bar', 'baz' => 'foo' ), 'Several attributes' ); - - $this->assertEquals( Sanitizer::decodeTagAttributes( ':foo=\'bar\'' ), array( ':foo' => 'bar' ), 'Leading :' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( '_foo=\'bar\'' ), array( '_foo' => 'bar' ), 'Leading _' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'Foo=\'bar\'' ), array( 'foo' => 'bar' ), 'Leading capital' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'FOO=BAR' ), array( 'foo' => 'BAR' ), 'Attribute keys are normalized to lowercase' ); - - # Invalid beginning - $this->assertEquals( Sanitizer::decodeTagAttributes( '-foo=bar' ), array(), 'Leading - is forbidden' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( '.foo=bar' ), array(), 'Leading . is forbidden' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo-bar=bar' ), array( 'foo-bar' => 'bar' ), 'A - is allowed inside the attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo-=bar' ), array( 'foo-' => 'bar' ), 'A - is allowed inside the attribute' ); - - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo.bar=baz' ), array( 'foo.bar' => 'baz' ), 'A . is allowed inside the attribute' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo.=baz' ), array( 'foo.' => 'baz' ), 'A . is allowed as last character' ); - - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo6=baz' ), array( 'foo6' => 'baz' ), 'Numbers are allowed' ); - - # This bit is more relaxed than XML rules, but some extensions use it, like ProofreadPage (see bug 27539) - $this->assertEquals( Sanitizer::decodeTagAttributes( '1foo=baz' ), array( '1foo' => 'baz' ), 'Leading numbers are allowed' ); - - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo$=baz' ), array(), 'Symbols are not allowed' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo@=baz' ), array(), 'Symbols are not allowed' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo~=baz' ), array(), 'Symbols are not allowed' ); - - - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=1[#^`*%w/(' ), array( 'foo' => '1[#^`*%w/(' ), 'All kind of characters are allowed as values' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo="1[#^`*%\'w/("' ), array( 'foo' => '1[#^`*%\'w/(' ), 'Double quotes are allowed if quoted by single quotes' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=\'1[#^`*%"w/(\'' ), array( 'foo' => '1[#^`*%"w/(' ), 'Single quotes are allowed if quoted by double quotes' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=&"' ), array( 'foo' => '&"' ), 'Special chars can be provided as entities' ); - $this->assertEquals( Sanitizer::decodeTagAttributes( 'foo=&foobar;' ), array( 'foo' => '&foobar;' ), 'Entity-like items are accepted' ); - } - - /** - * @dataProvider provideDeprecatedAttributes - */ - function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl ) { - $this->assertEquals( " $inputAttr", Sanitizer::fixTagAttributes( $inputAttr, $inputEl ) ); - } - - public static function provideDeprecatedAttributes() { - return array( - array( 'clear="left"', 'br' ), - array( 'clear="all"', 'br' ), - array( 'width="100"', 'td' ), - array( 'nowrap="true"', 'td' ), - array( 'nowrap=""', 'td' ), - array( 'align="right"', 'td' ), - array( 'align="center"', 'table' ), - array( 'align="left"', 'tr' ), - array( 'align="center"', 'div' ), - array( 'align="left"', 'h1' ), - array( 'align="left"', 'span' ), - ); - } - - /** - * @dataProvider provideCssCommentsFixtures - */ - function testCssCommentsChecking( $expected, $css, $message = '' ) { - $this->assertEquals( - $expected, - Sanitizer::checkCss( $css ), - $message - ); - } - - function provideCssCommentsFixtures() { - /** array( , , [message] ) */ - return array( - array( ' ', '/**/' ), - array( ' ', '/****/' ), - array( ' ', '/* comment */' ), - array( ' ', "\\2f\\2a foo \\2a\\2f", - 'Backslash-escaped comments must be stripped (bug 28450)' ), - array( '', '/* unfinished comment structure', - 'Remove anything after a comment-start token' ), - array( '', "\\2f\\2a unifinished comment'", - 'Remove anything after a backslash-escaped comment-start token' ), - ); - } -} - diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php deleted file mode 100644 index 14d799cf..00000000 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ /dev/null @@ -1,79 +0,0 @@ -assertEquals( - $expected, - Sanitizer::validateEmail( $addr ), - $msg - ); - } - private function valid( $addr, $msg = '' ) { - $this->checkEmail( $addr, true, $msg ); - } - private function invalid( $addr, $msg = '' ) { - $this->checkEmail( $addr, false, $msg ); - } - - function testEmailWellKnownUserAtHostDotTldAreValid() { - $this->valid( 'user@example.com' ); - $this->valid( 'user@example.museum' ); - } - function testEmailWithUpperCaseCharactersAreValid() { - $this->valid( 'USER@example.com' ); - $this->valid( 'user@EXAMPLE.COM' ); - $this->valid( 'user@Example.com' ); - $this->valid( 'USER@eXAMPLE.com' ); - } - function testEmailWithAPlusInUserName() { - $this->valid( 'user+sub@example.com' ); - $this->valid( 'user+@example.com' ); - } - function testEmailDoesNotNeedATopLevelDomain() { - $this->valid( "user@localhost" ); - $this->valid( "FooBar@localdomain" ); - $this->valid( "nobody@mycompany" ); - } - function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { - $this->invalid( " user@host.com" ); - $this->invalid( "user@host.com " ); - $this->invalid( "\tuser@host.com" ); - $this->invalid( "user@host.com\t" ); - } - function testEmailWithWhiteSpacesAreInvalids() { - $this->invalid( "User user@host" ); - $this->invalid( "first last@mycompany" ); - $this->invalid( "firstlast@my company" ); - } - // bug 26948 : comma were matched by an incorrect regexp range - function testEmailWithCommasAreInvalids() { - $this->invalid( "user,foo@example.org" ); - $this->invalid( "userfoo@ex,ample.org" ); - } - function testEmailWithHyphens() { - $this->valid( "user-foo@example.org" ); - $this->valid( "userfoo@ex-ample.org" ); - } - function testEmailDomainCanNotBeginWithDot() { - $this->invalid( "user@." ); - $this->invalid( "user@.localdomain" ); - $this->invalid( "user@localdomain." ); - $this->valid( "user.@localdomain" ); - $this->valid( ".@localdomain" ); - $this->invalid( ".@a............" ); - } - function testEmailWithFunnyCharacters() { - $this->valid( "\$user!ex{this}@123.com" ); - } - function testEmailTopLevelDomainCanBeNumerical() { - $this->valid( "user@example.1234" ); - } - function testEmailWithoutAtSignIsInvalid() { - $this->invalid( 'useràexample.com' ); - } - function testEmailWithOneCharacterDomainIsValid() { - $this->valid( 'user@a' ); - } -} diff --git a/tests/phpunit/includes/SeleniumConfigurationTest.php b/tests/phpunit/includes/SeleniumConfigurationTest.php deleted file mode 100644 index 8589c188..00000000 --- a/tests/phpunit/includes/SeleniumConfigurationTest.php +++ /dev/null @@ -1,228 +0,0 @@ - '*firefox', - 'iexplorer' => '*iexploreproxy', - 'chrome' => '*chrome' - ); - /** - * Array of expected selenium settings from $testConfig0 - */ - private $testSettings0 = array( - 'host' => 'localhost', - 'port' => 'foobarr', - 'wikiUrl' => 'http://localhost/deployment', - 'username' => 'xxxxxxx', - 'userPassword' => '', - 'testBrowser' => 'chrome', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Array of expected testSuites from $testConfig0 - */ - private $testSuites0 = array( - 'SimpleSeleniumTestSuite' => 'tests/selenium/SimpleSeleniumTestSuite.php', - 'TestSuiteName' => 'testSuitePath' - ); - - - /** - * Another sample selenium settings file contents - */ - private $testConfig1 = -' -[SeleniumSettings] -host = "localhost" -testBrowser = "firefox" -'; - /** - * Expected browsers from $testConfig1 - */ - private $testBrowsers1 = null; - /** - * Expected selenium settings from $testConfig1 - */ - private $testSettings1 = array( - 'host' => 'localhost', - 'port' => null, - 'wikiUrl' => null, - 'username' => null, - 'userPassword' => null, - 'testBrowser' => 'firefox', - 'startserver' => null, - 'stopserver' => null, - 'seleniumserverexecpath' => null, - 'jUnitLogFile' => null, - 'runAgainstGrid' => null - ); - /** - * Expected test suites from $testConfig1 - */ - private $testSuites1 = null; - - - public function setUp() { - if ( !defined( 'SELENIUMTEST' ) ) { - define( 'SELENIUMTEST', true ); - } - } - - /** - * Clean up the temporary file used to store the selenium settings. - */ - public function tearDown() { - if ( strlen( $this->tempFileName ) > 0 ) { - unlink( $this->tempFileName ); - unset( $this->tempFileName ); - } - parent::tearDown(); - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnIncorrectConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - - SeleniumConfig::getSeleniumSettings($seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - "Some_fake_settings_file.ini" ); - - } - - /** - * @expectedException MWException - * @group SeleniumFramework - */ - public function testErrorOnMissingConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $wgSeleniumConfigFile = ''; - SeleniumConfig::getSeleniumSettings($seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites); - } - - /** - * @group SeleniumFramework - */ - public function testUsesGlobalVarForConfigFile() { - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = array(); - global $wgSeleniumConfigFile; - $this->writeToTempFile( $this->testConfig0 ); - $wgSeleniumConfigFile = $this->tempFileName; - SeleniumConfig::getSeleniumSettings($seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites); - $this->assertEquals($seleniumSettings, $this->testSettings0 , - 'The selenium settings should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals($seleniumBrowsers, $this->testBrowsers0, - 'The available browsers should have been read from the file defined in $wgSeleniumConfigFile' - ); - $this->assertEquals($seleniumTestSuites, $this->testSuites0, - 'The test suites should have been read from the file defined in $wgSeleniumConfigFile' - ); - } - - /** - * @group SeleniumFramework - * @dataProvider sampleConfigs - */ - public function testgetSeleniumSettings($sampleConfig, $expectedSettings, $expectedBrowsers, $expectedSuites ) { - $this->writeToTempFile( $sampleConfig ); - $seleniumSettings = array(); - $seleniumBrowsers = array(); - $seleniumTestSuites = null; - - SeleniumConfig::getSeleniumSettings($seleniumSettings, - $seleniumBrowsers, - $seleniumTestSuites, - $this->tempFileName ); - - $this->assertEquals($seleniumSettings, $expectedSettings, - "The selenium settings for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals($seleniumBrowsers, $expectedBrowsers, - "The available browsers for the following test configuration was not retrieved correctly" . $sampleConfig - ); - $this->assertEquals($seleniumTestSuites, $expectedSuites, - "The test suites for the following test configuration was not retrieved correctly" . $sampleConfig - ); - - - } - - /** - * create a temp file and write text to it. - * @param $testToWrite the text to write to the temp file - */ - private function writeToTempFile($textToWrite) { - $this->tempFileName = tempnam(sys_get_temp_dir(), 'test_settings.'); - $tempFile = fopen( $this->tempFileName, "w" ); - fwrite($tempFile , $textToWrite); - fclose($tempFile); - } - - /** - * Returns an array containing: - * The contents of the selenium cingiguration ini file - * The expected selenium configuration array that getSeleniumSettings should return - * The expected available browsers array that getSeleniumSettings should return - * The expected test suites arrya that getSeleniumSettings should return - */ - public function sampleConfigs() { - return array( - array($this->testConfig0, $this->testSettings0, $this->testBrowsers0, $this->testSuites0 ), - array($this->testConfig1, $this->testSettings1, $this->testBrowsers1, $this->testSuites1 ) - ); - } - - -} diff --git a/tests/phpunit/includes/SiteConfigurationTest.php b/tests/phpunit/includes/SiteConfigurationTest.php deleted file mode 100644 index 57d3532a..00000000 --- a/tests/phpunit/includes/SiteConfigurationTest.php +++ /dev/null @@ -1,311 +0,0 @@ -suffixes as $suffix ) { - if ( substr( $wiki, -strlen( $suffix ) ) == $suffix ) { - $site = $suffix; - $lang = substr( $wiki, 0, -strlen( $suffix ) ); - break; - } - } - return array( - 'suffix' => $site, - 'lang' => $lang, - 'params' => array( - 'lang' => $lang, - 'site' => $site, - 'wiki' => $wiki, - ), - 'tags' => array( 'tag' ), - ); -} - -class SiteConfigurationTest extends MediaWikiTestCase { - var $mConf; - - function setUp() { - $this->mConf = new SiteConfiguration; - - $this->mConf->suffixes = array( 'wiki' ); - $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); - $this->mConf->settings = array( - 'simple' => array( - 'wiki' => 'wiki', - 'tag' => 'tag', - 'enwiki' => 'enwiki', - 'dewiki' => 'dewiki', - 'frwiki' => 'frwiki', - ), - - 'fallback' => array( - 'default' => 'default', - 'wiki' => 'wiki', - 'tag' => 'tag', - ), - - 'params' => array( - 'default' => '$lang $site $wiki', - ), - - '+global' => array( - 'wiki' => array( - 'wiki' => 'wiki', - ), - 'tag' => array( - 'tag' => 'tag', - ), - 'enwiki' => array( - 'enwiki' => 'enwiki', - ), - 'dewiki' => array( - 'dewiki' => 'dewiki', - ), - 'frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - - 'merge' => array( - '+wiki' => array( - 'wiki' => 'wiki', - ), - '+tag' => array( - 'tag' => 'tag', - ), - 'default' => array( - 'default' => 'default', - ), - '+enwiki' => array( - 'enwiki' => 'enwiki', - ), - '+dewiki' => array( - 'dewiki' => 'dewiki', - ), - '+frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - ); - - $GLOBALS['global'] = array( 'global' => 'global' ); - } - - - function testSiteFromDb() { - $this->assertEquals( - array( 'wikipedia', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB()' - ); - $this->assertEquals( - array( 'wikipedia', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki' - ); - - $this->mConf->suffixes = array( 'wiki', '' ); - $this->assertEquals( - array( '', 'wikien' ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki (2)' - ); - } - - function testGetLocalDatabases() { - $this->assertEquals( - array( 'enwiki', 'dewiki', 'frwiki' ), - $this->mConf->getLocalDatabases(), - 'getLocalDatabases()' - ); - } - - function testGetConfVariables() { - $this->assertEquals( - 'enwiki', - $this->mConf->get( 'simple', 'enwiki', 'wiki' ), - 'get(): simple setting on an existing wiki' - ); - $this->assertEquals( - 'dewiki', - $this->mConf->get( 'simple', 'dewiki', 'wiki' ), - 'get(): simple setting on an existing wiki (2)' - ); - $this->assertEquals( - 'frwiki', - $this->mConf->get( 'simple', 'frwiki', 'wiki' ), - 'get(): simple setting on an existing wiki (3)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'wiki', 'wiki' ), - 'get(): simple setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'eswiki', 'wiki' ), - 'get(): simple setting on an non-existing wiki' - ); - - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'enwiki', 'wiki' ), - 'get(): fallback setting on an existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an existing wiki (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki' ), - 'get(): fallback setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an suffix (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'eswiki', 'wiki' ), - 'get(): fallback setting on an non-existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an non-existing wiki (with wiki tag)' - ); - - $common = array( 'wiki' => 'wiki', 'default' => 'default' ); - $commonTag = array( 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $common, - $this->mConf->get( 'merge', 'enwiki', 'wiki' ), - 'get(): merging setting on an existing wiki' - ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'enwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (with tag)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $common, - $this->mConf->get( 'merge', 'dewiki', 'wiki' ), - 'get(): merging setting on an existing wiki (2)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $commonTag, - $this->mConf->get( 'merge', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (2) (with tag)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $common, - $this->mConf->get( 'merge', 'frwiki', 'wiki' ), - 'get(): merging setting on an existing wiki (3)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'frwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (3) (with tag)' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $common, - $this->mConf->get( 'merge', 'wiki', 'wiki' ), - 'get(): merging setting on an suffix' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $commonTag, - $this->mConf->get( 'merge', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an suffix (with tag)' - ); - $this->assertEquals( - $common, - $this->mConf->get( 'merge', 'eswiki', 'wiki' ), - 'get(): merging setting on an non-existing wiki' - ); - $this->assertEquals( - $commonTag, - $this->mConf->get( 'merge', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an non-existing wiki (with tag)' - ); - } - - function testSiteFromDbWithCallback() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - array( 'wiki', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB() with callback' - ); - $this->assertEquals( - array( 'wiki', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() with callback on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() with callback on a non-existing wiki' - ); - } - - function testParameterReplacement() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - 'en wiki enwiki', - $this->mConf->get( 'params', 'enwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki' - ); - $this->assertEquals( - 'de wiki dewiki', - $this->mConf->get( 'params', 'dewiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (2)' - ); - $this->assertEquals( - 'fr wiki frwiki', - $this->mConf->get( 'params', 'frwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (3)' - ); - $this->assertEquals( - ' wiki wiki', - $this->mConf->get( 'params', 'wiki', 'wiki' ), - 'get(): parameter replacement on an suffix' - ); - $this->assertEquals( - 'es wiki eswiki', - $this->mConf->get( 'params', 'eswiki', 'wiki' ), - 'get(): parameter replacement on an non-existing wiki' - ); - } - - function testGetAllGlobals() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $getall = array( - 'simple' => 'enwiki', - 'fallback' => 'tag', - 'params' => 'en wiki enwiki', - 'global' => array( 'enwiki' => 'enwiki' ) + $GLOBALS['global'], - 'merge' => array( 'enwiki' => 'enwiki', 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ), - ); - $this->assertEquals( $getall, $this->mConf->getAll( 'enwiki' ), 'getAll()' ); - - $this->mConf->extractAllGlobals( 'enwiki', 'wiki' ); - - $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' ); - $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' ); - $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' ); - $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' ); - $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' ); - } -} diff --git a/tests/phpunit/includes/TemplateCategoriesTest.php b/tests/phpunit/includes/TemplateCategoriesTest.php deleted file mode 100644 index 39ce6e31..00000000 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ /dev/null @@ -1,36 +0,0 @@ -mRights = array( 'createpage', 'edit', 'purge' ); - - $status = $page->doEdit( '{{Categorising template}}', 'Create a page with a template', 0, false, $user ); - $this->assertEquals( - array() - , $title->getParentCategories() - ); - - $template = WikiPage::factory( Title::newFromText( 'Template:Categorising template' ) ); - $status = $template->doEdit( '[[Category:Solved bugs]]', 'Add a category through a template', 0, false, $user ); - - // Run the job queue - $jobs = new RunJobs; - $jobs->loadParamsAndArgs( null, array( 'quiet' => true ), null ); - $jobs->execute(); - - $this->assertEquals( - array( 'Category:Solved_bugs' => $title->getPrefixedText() ) - , $title->getParentCategories() - ); - } - -} diff --git a/tests/phpunit/includes/TestUser.php b/tests/phpunit/includes/TestUser.php deleted file mode 100644 index c4d89455..00000000 --- a/tests/phpunit/includes/TestUser.php +++ /dev/null @@ -1,58 +0,0 @@ -username = $username; - $this->realname = $realname; - $this->email = $email; - $this->groups = $groups; - - // don't allow user to hardcode or select passwords -- people sometimes run tests - // on live wikis. Sometimes we create sysop users in these tests. A sysop user with - // a known password would be a Bad Thing. - $this->password = User::randomPassword(); - - $this->user = User::newFromName( $this->username ); - $this->user->load(); - - // In an ideal world we'd have a new wiki (or mock data store) for every single test. - // But for now, we just need to create or update the user with the desired properties. - // we particularly need the new password, since we just generated it randomly. - // In core MediaWiki, there is no functionality to delete users, so this is the best we can do. - if ( !$this->user->getID() ) { - // create the user - $this->user = User::createNew( - $this->username, array( - "email" => $this->email, - "real_name" => $this->realname - ) - ); - if ( !$this->user ) { - throw new Exception( "error creating user" ); - } - } - - // update the user to use the new random password and other details - $this->user->setPassword( $this->password ); - $this->user->setEmail( $this->email ); - $this->user->setRealName( $this->realname ); - // remove all groups, replace with any groups specified - foreach ( $this->user->getGroups() as $group ) { - $this->user->removeGroup( $group ); - } - if ( count( $this->groups ) ) { - foreach ( $this->groups as $group ) { - $this->user->addGroup( $group ); - } - } - $this->user->saveSettings(); - - } -} diff --git a/tests/phpunit/includes/TimeAdjustTest.php b/tests/phpunit/includes/TimeAdjustTest.php deleted file mode 100644 index cd027c5b..00000000 --- a/tests/phpunit/includes/TimeAdjustTest.php +++ /dev/null @@ -1,51 +0,0 @@ -iniSet( 'precision', 15 ); - } - - public function tearDown() { - global $wgLocalTZoffset; - $wgLocalTZoffset = self::$offset; - parent::tearDown(); - } - - # Test offset usage for a given language::userAdjust - function testUserAdjust() { - global $wgLocalTZoffset, $wgContLang; - - $wgContLang = $en = Language::factory( 'en' ); - - #  Collection of parameters for Language_t_Offset. - # Format: date to be formatted, localTZoffset value, expected date - $userAdjust_tests = array( - array( 20061231235959, 0, 20061231235959 ), - array( 20061231235959, 5, 20070101000459 ), - array( 20061231235959, 15, 20070101001459 ), - array( 20061231235959, 60, 20070101005959 ), - array( 20061231235959, 90, 20070101012959 ), - array( 20061231235959, 120, 20070101015959 ), - array( 20061231235959, 540, 20070101085959 ), - array( 20061231235959, -5, 20061231235459 ), - array( 20061231235959, -30, 20061231232959 ), - array( 20061231235959, -60, 20061231225959 ), - ); - - foreach ( $userAdjust_tests as $data ) { - $wgLocalTZoffset = $data[1]; - - $this->assertEquals( - strval( $data[2] ), - strval( $en->userAdjust( $data[0], '' ) ), - "User adjust {$data[0]} by {$data[1]} minutes should give {$data[2]}" - ); - } - } -} diff --git a/tests/phpunit/includes/TimestampTest.php b/tests/phpunit/includes/TimestampTest.php deleted file mode 100644 index 231228f5..00000000 --- a/tests/phpunit/includes/TimestampTest.php +++ /dev/null @@ -1,72 +0,0 @@ -assertEquals( $expected, $timestamp->getTimestamp( TS_MW ) ); - } - - /** - * Test outputting valid timestamps to different formats. - * @dataProvider provideValidTimestamps - */ - function testValidOutput( $format, $expected, $original ) { - $timestamp = new MWTimestamp( $original ); - $this->assertEquals( $expected, (string) $timestamp->getTimestamp( $format ) ); - } - - /** - * Test an invalid timestamp. - * @expectedException TimestampException - */ - function testInvalidParse() { - $timestamp = new MWTimestamp( "This is not a timestamp." ); - } - - /** - * Test requesting an invalid output format. - * @expectedException TimestampException - */ - function testInvalidOutput() { - $timestamp = new MWTimestamp( '1343761268' ); - $timestamp->getTimestamp( 98 ); - } - - /** - * Test human readable timestamp format. - */ - function testHumanOutput() { - $timestamp = new MWTimestamp( time() - 3600 ); - $this->assertEquals( "1 hour ago", $timestamp->getHumanTimestamp()->toString() ); - } - - /** - * Returns a list of valid timestamps in the format: - * array( type, timestamp_of_type, timestamp_in_MW ) - */ - function provideValidTimestamps() { - return array( - // Various formats - array( TS_UNIX, '1343761268', '20120731190108' ), - array( TS_MW, '20120731190108', '20120731190108' ), - array( TS_DB, '2012-07-31 19:01:08', '20120731190108' ), - array( TS_ISO_8601, '2012-07-31T19:01:08Z', '20120731190108' ), - array( TS_ISO_8601_BASIC, '20120731T190108Z', '20120731190108' ), - array( TS_EXIF, '2012:07:31 19:01:08', '20120731190108' ), - array( TS_RFC2822, 'Tue, 31 Jul 2012 19:01:08 GMT', '20120731190108' ), - array( TS_ORACLE, '31-07-2012 19:01:08.000000', '20120731190108' ), - array( TS_POSTGRES, '2012-07-31 19:01:08 GMT', '20120731190108' ), - array( TS_DB2, '2012-07-31 19:01:08', '20120731190108' ), - // Some extremes and weird values - array( TS_ISO_8601, '9999-12-31T23:59:59Z', '99991231235959' ), - array( TS_UNIX, '-62135596801', '00001231235959' ) - ); - } -} diff --git a/tests/phpunit/includes/TitleMethodsTest.php b/tests/phpunit/includes/TitleMethodsTest.php deleted file mode 100644 index aed658ba..00000000 --- a/tests/phpunit/includes/TitleMethodsTest.php +++ /dev/null @@ -1,201 +0,0 @@ -assertEquals( $expectedBool, $titleA->equals( $titleB ) ); - $this->assertEquals( $expectedBool, $titleB->equals( $titleA ) ); - } - - public function dataInNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, false ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, false ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, false ), - ); - } - - /** - * @dataProvider dataInNamespace - */ - public function testInNamespace( $title, $ns, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->inNamespace( $ns ) ); - } - - public function testInNamespaces() { - $mainpage = Title::newFromText( 'Main Page' ); - $this->assertTrue( $mainpage->inNamespaces( NS_MAIN, NS_USER ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_MAIN, NS_USER ) ) ); - $this->assertTrue( $mainpage->inNamespaces( array( NS_USER, NS_MAIN ) ) ); - $this->assertFalse( $mainpage->inNamespaces( array( NS_PROJECT, NS_TEMPLATE ) ) ); - } - - public function dataHasSubjectNamespace() { - return array( - array( 'Main Page', NS_MAIN, true ), - array( 'Main Page', NS_TALK, true ), - array( 'Main Page', NS_USER, false ), - array( 'User:Foo', NS_USER, true ), - array( 'User:Foo', NS_USER_TALK, true ), - array( 'User:Foo', NS_TEMPLATE, false ), - array( 'User_talk:Foo', NS_USER_TALK, true ), - array( 'User_talk:Foo', NS_USER, true ), - ); - } - - /** - * @dataProvider dataHasSubjectNamespace - */ - public function testHasSubjectNamespace( $title, $ns, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->hasSubjectNamespace( $ns ) ); - } - - public function dataIsCssOrJsPage() { - return array( - array( 'Foo', false ), - array( 'Foo.js', false ), - array( 'Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', true ), - array( 'MediaWiki:Foo.css', true ), - array( 'MediaWiki:Foo.JS', false ), - array( 'MediaWiki:Foo.CSS', false ), - array( 'MediaWiki:Foo.css.xxx', false ), - ); - } - - /** - * @dataProvider dataIsCssOrJsPage - */ - public function testIsCssOrJsPage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssOrJsPage() ); - } - - - public function dataIsCssJsSubpage() { - return array( - array( 'Foo', false ), - array( 'Foo.js', false ), - array( 'Foo/bar.js', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', true ), - array( 'User talk:Foo/bar.css', false ), - array( 'User:Foo/bar.js.xxx', false ), - array( 'User:Foo/bar.xxx', false ), - array( 'MediaWiki:Foo.js', false ), - array( 'User:Foo/bar.JS', false ), - array( 'User:Foo/bar.CSS', false ), - ); - } - - /** - * @dataProvider dataIsCssJsSubpage - */ - public function testIsCssJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssJsSubpage() ); - } - - public function dataIsCssSubpage() { - return array( - array( 'Foo', false ), - array( 'Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', true ), - ); - } - - /** - * @dataProvider dataIsCssSubpage - */ - public function testIsCssSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isCssSubpage() ); - } - - public function dataIsJsSubpage() { - return array( - array( 'Foo', false ), - array( 'Foo.css', false ), - array( 'User:Foo', false ), - array( 'User:Foo.js', false ), - array( 'User:Foo.css', false ), - array( 'User:Foo/bar.js', true ), - array( 'User:Foo/bar.css', false ), - ); - } - - /** - * @dataProvider dataIsJsSubpage - */ - public function testIsJsSubpage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isJsSubpage() ); - } - - public function dataIsWikitextPage() { - return array( - array( 'Foo', true ), - array( 'Foo.js', true ), - array( 'Foo/bar.js', true ), - array( 'User:Foo', true ), - array( 'User:Foo.js', true ), - array( 'User:Foo/bar.js', false ), - array( 'User:Foo/bar.css', false ), - array( 'User talk:Foo/bar.css', true ), - array( 'User:Foo/bar.js.xxx', true ), - array( 'User:Foo/bar.xxx', true ), - array( 'MediaWiki:Foo.js', false ), - array( 'MediaWiki:Foo.css', false ), - array( 'MediaWiki:Foo/bar.css', false ), - array( 'User:Foo/bar.JS', true ), - array( 'User:Foo/bar.CSS', true ), - ); - } - - /** - * @dataProvider dataIsWikitextPage - */ - public function testIsWikitextPage( $title, $expectedBool ) { - $title = Title::newFromText( $title ); - $this->assertEquals( $expectedBool, $title->isWikitextPage() ); - } - -} diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php deleted file mode 100644 index f62ac5dd..00000000 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ /dev/null @@ -1,660 +0,0 @@ -userName = "Useruser"; - $this->altUserName = "Altuseruser"; - date_default_timezone_set( $wgLocaltimezone ); - $wgLocalTZoffset = date( "Z" ) / 60; - - $this->title = Title::makeTitle( NS_MAIN, "Main Page" ); - if ( !isset( $this->userUser ) || !( $this->userUser instanceOf User ) ) { - $this->userUser = User::newFromName( $this->userName ); - - if ( !$this->userUser->getID() ) { - $this->userUser = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - $this->userUser->load(); - } - - $this->altUser = User::newFromName( $this->altUserName ); - if ( !$this->altUser->getID() ) { - $this->altUser = User::createNew( $this->altUserName, array( - "email" => "alttest@example.com", - "real_name" => "Test User Alt" ) ); - $this->altUser->load(); - } - - $this->anonUser = User::newFromId( 0 ); - - $this->user = $this->userUser; - } - } - - function tearDown() { - parent::tearDown(); - } - - function setUserPerm( $perm ) { - // Setting member variables is evil!!! - - if ( is_array( $perm ) ) { - $this->user->mRights = $perm; - } else { - $this->user->mRights = array( $perm ); - } - } - - function setTitle( $ns, $title = "Main_Page" ) { - $this->title = Title::makeTitle( $ns, $title ); - } - - function setUser( $userName = null ) { - if ( $userName === 'anon' ) { - $this->user = $this->anonUser; - } elseif ( $userName === null || $userName === $this->userName ) { - $this->user = $this->userUser; - } else { - $this->user = $this->altUser; - } - - global $wgUser; - $wgUser = $this->user; - } - - function testQuickPermissions() { - global $wgContLang; - $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( "nocreatetext" ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), - array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) ); - - $this->setTitle( NS_MAIN ); - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ), - array( array( 'movenologintext' ) ) ); - - $this->setUser( $this->userName ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) ); - - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( '' ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_USER ); - $this->setUser( $this->userName ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( array( 'cant-move-to-user-page' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( "move" ); - $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); - $this->assertEquals( array( ), $res ); - - $this->setUser( 'anon' ); - $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ), - array( array( 'badaccess-group0' ) ), - array( ), true ), - 'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ), - array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ), - array( array( 'protect-cantedit' ) ), false ), - '' => array( array( ), array( ), array( ), true ) ); - global $wgUser; - $wgUser = $this->user; - foreach ( array( "edit", "protect", "" ) as $action ) { - $this->setUserPerm( null ); - $this->assertEquals( $check[$action][0], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - global $wgGroupPermissions; - $old = $wgGroupPermissions; - $wgGroupPermissions = array(); - - $this->assertEquals( $check[$action][1], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - $wgGroupPermissions = $old; - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][2], - $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][3], - $this->title->userCan( $action, true ) ); - $this->assertEquals( $check[$action][3], - $this->title->quickUserCan( $action ) ); - - # count( User::getGroupsWithPermissions( $action ) ) < 1 - } - } - - function runGroupPermissions( $action, $result, $result2 = null ) { - global $wgGroupPermissions; - - if ( $result2 === null ) $result2 = $result; - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = false; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = true; - $res = $this->title->getUserPermissionsErrors( $action, $this->user ); - $this->assertEquals( $result2, $res ); - } - - function testSpecialsAndNSPermissions() { - $this->setUser( $this->userName ); - global $wgUser; - $wgUser = $this->user; - - $this->setTitle( NS_SPECIAL ); - - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'execute', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - global $wgNamespaceProtection; - $wgNamespaceProtection[NS_USER] = array ( 'bogus' ); - $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $wgNamespaceProtection = null; - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'bogus' ) ); - - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'bogus' ) ); - } - - function testCssAndJavascriptPermissions() { - $this->setUser( $this->userName ); - global $wgUser; - $wgUser = $this->user; - - $this->setTitle( NS_USER, $this->altUserName . '/test.js' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), - array( array( 'badaccess-group0' ), array( 'customjsprotected' ) ), - array( array( 'badaccess-group0' ) ) ); - - $this->setTitle( NS_USER, $this->altUserName . '/test.css' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ), - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ), array( 'customcssprotected' ) ) ); - - $this->setTitle( NS_USER, $this->altUserName . '/tempo' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ) ); - } - - function runCSSandJSPermissions( $result0, $result1, $result2 ) { - $this->setUserPerm( '' ); - $this->assertEquals( $result0, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( 'editusercss' ); - $this->assertEquals( $result1, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( 'edituserjs' ); - $this->assertEquals( $result2, - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( 'editusercssjs' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - - $this->setUserPerm( array( 'edituserjs', 'editusercss' ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - } - - function testPageRestrictions() { - global $wgUser, $wgContLang; - - $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); - - $wgUser = $this->user; - $this->setTitle( NS_MAIN ); - $this->title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); - $this->title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - - $this->assertEquals( true, - $this->title->quickUserCan( 'edit' ) ); - $this->title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ), - "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - $this->setUserPerm( "" ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - $this->setUserPerm( array( "edit", "editprotected" ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - $this->title->mCascadeRestriction = true; - $this->assertEquals( false, - $this->title->quickUserCan( 'bogus' ) ); - $this->assertEquals( false, - $this->title->quickUserCan( 'edit' ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'bogus', - $this->user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - $this->title->getUserPermissionsErrors( 'edit', - $this->user ) ); - } - - function testCascadingSourcesRestrictions() { - global $wgUser; - $wgUser = $this->user; - $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( array( "edit", "bogus" ) ); - - $this->title->mCascadeSources = array( Title::makeTitle( NS_MAIN, "Bogus" ), Title::makeTitle( NS_MAIN, "UnBogus" ) ); - $this->title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( false, - $this->title->userCan( 'bogus' ) ); - $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), - array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ), - $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); - - $this->assertEquals( true, - $this->title->userCan( 'edit' ) ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - - } - - function testActionPermissions() { - global $wgUser; - $wgUser = $this->user; - - $this->setUserPerm( array( "createpage" ) ); - $this->setTitle( NS_MAIN, "test page" ); - $this->title->mTitleProtection['pt_create_perm'] = ''; - $this->title->mTitleProtection['pt_user'] = $this->user->getID(); - $this->title->mTitleProtection['pt_expiry'] = wfGetDB( DB_SLAVE )->getInfinity(); - $this->title->mTitleProtection['pt_reason'] = 'test'; - $this->title->mCascadeRestriction = false; - - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - $this->title->getUserPermissionsErrors( 'create', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'create' ) ); - - $this->title->mTitleProtection['pt_create_perm'] = 'sysop'; - $this->setUserPerm( array( 'createpage', 'protect' ) ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'create', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'create' ) ); - - - $this->setUserPerm( array( 'createpage' ) ); - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - $this->title->getUserPermissionsErrors( 'create', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'create' ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( array( "move" ) ); - $this->assertEquals( false, - $this->title->userCan( 'move' ) ); - $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - - $this->setTitle( NS_MAIN, "test page" ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move' ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-source-page' ) ), - $this->title->getUserPermissionsErrors( 'move', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move' ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->assertEquals( false, - $this->title->userCan( 'move-target' ) ); - $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - - $this->setTitle( NS_MAIN, "test page" ); - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( true, - $this->title->userCan( 'move-target' ) ); - - $this->title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-target-page' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $this->assertEquals( false, - $this->title->userCan( 'move-target' ) ); - - } - - function testUserBlock() { - global $wgUser, $wgEmailConfirmToEdit, $wgEmailAuthentication; - $wgEmailConfirmToEdit = true; - $wgEmailAuthentication = true; - $wgUser = $this->user; - - $this->setUserPerm( array( "createpage", "move" ) ); - $this->setTitle( NS_MAIN, "test page" ); - - # $short - $this->assertEquals( array( array( 'confirmedittext' ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - $wgEmailConfirmToEdit = false; - $this->assertEquals( true, $this->title->userCan( 'move-target' ) ); - - # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' - $this->assertEquals( array( ), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - global $wgLang; - $prev = time(); - $now = time() + 120; - $this->user->mBlockedby = $this->user->getId(); - $this->user->mBlock = new Block( '127.0.8.1', 0, $this->user->getId(), - 'no reason given', $prev + 3600, 1, 0 ); - $this->user->mBlock->mTimestamp = 0; - $this->assertEquals( array( array( 'autoblockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', null, 'infinite', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ), - $this->title->getUserPermissionsErrors( 'move-target', - $this->user ) ); - - $this->assertEquals( false, $this->title->userCan( 'move-target' ) ); - // quickUserCan should ignore user blocks - $this->assertEquals( true, $this->title->quickUserCan( 'move-target' ) ); - - global $wgLocalTZoffset; - $wgLocalTZoffset = -60; - $this->user->mBlockedby = $this->user->getName(); - $this->user->mBlock = new Block( '127.0.8.1', 0, 1, 'no reason given', $now, 0, 10 ); - $this->assertEquals( array( array( 'blockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ), - $this->title->getUserPermissionsErrors( 'move-target', $this->user ) ); - - # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) - # $user->blockedFor() == '' - # $user->mBlock->mExpiry == 'infinity' - } -} diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php deleted file mode 100644 index f61652df..00000000 --- a/tests/phpunit/includes/TitleTest.php +++ /dev/null @@ -1,155 +0,0 @@ -|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) { - $this->assertFalse( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is not a valid titlechar" ); - } else { - $this->assertTrue( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is a valid titlechar" ); - } - } - } - - /** - * @dataProvider dataBug31100 - */ - function testBug31100FixSpecialName( $text, $expectedParam ) { - $title = Title::newFromText( $text ); - $fixed = $title->fixSpecialName(); - $stuff = explode( '/', $fixed->getDbKey(), 2 ); - if ( count( $stuff ) == 2 ) { - $par = $stuff[1]; - } else { - $par = null; - } - $this->assertEquals( $expectedParam, $par, "Bug 31100 regression check: Title->fixSpecialName() should preserve parameter" ); - } - - function dataBug31100() { - return array( - array( 'Special:Version', null ), - array( 'Special:Version/', '' ), - array( 'Special:Version/param', 'param' ), - ); - } - - /** - * Auth-less test of Title::isValidMoveOperation - * - * @group Database - * @param string $source - * @param string $target - * @param array|string|true $expected Required error - * @dataProvider dataTestIsValidMoveOperation - */ - function testIsValidMoveOperation( $source, $target, $expected ) { - $title = Title::newFromText( $source ); - $nt = Title::newFromText( $target ); - $errors = $title->isValidMoveOperation( $nt, false ); - if ( $expected === true ) { - $this->assertTrue( $errors ); - } else { - $errors = $this->flattenErrorsArray( $errors ); - foreach ( (array)$expected as $error ) { - $this->assertContains( $error, $errors ); - } - } - } - - function flattenErrorsArray( $errors ) { - $result = array(); - foreach ( $errors as $error ) { - $result[] = $error[0]; - } - return $result; - } - - function dataTestIsValidMoveOperation() { - return array( - array( 'Test', 'Test', 'selfmove' ), - array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ) - ); - } - - - /** - * @dataProvider provideCasesForGetpageviewlanguage - */ - function testGetpageviewlanguage( $expected, $titleText, $contLang, $lang, $variant, $msg='' ) { - // Save globals - global $wgContLang, $wgLang, $wgAllowUserJs, $wgLanguageCode, $wgDefaultLanguageVariant; - $save['wgContLang'] = $wgContLang; - $save['wgLang'] = $wgLang; - $save['wgAllowUserJs'] = $wgAllowUserJs; - $save['wgLanguageCode'] = $wgLanguageCode; - $save['wgDefaultLanguageVariant'] = $wgDefaultLanguageVariant; - - // Setup test environnement: - $wgContLang = Language::factory( $contLang ); - $wgLang = Language::factory( $lang ); - # To test out .js titles: - $wgAllowUserJs = true; - $wgLanguageCode = $contLang; - $wgDefaultLanguageVariant = $variant; - - $title = Title::newFromText( $titleText ); - $this->assertInstanceOf( 'Title', $title, - "Test must be passed a valid title text, you gave '$titleText'" - ); - $this->assertEquals( $expected, - $title->getPageViewLanguage()->getCode(), - $msg - ); - - // Restore globals - $wgContLang = $save['wgContLang']; - $wgLang = $save['wgLang']; - $wgAllowUserJs = $save['wgAllowUserJs']; - $wgLanguageCode = $save['wgLanguageCode']; - $wgDefaultLanguageVariant = $save['wgDefaultLanguageVariant']; - } - - function provideCasesForGetpageviewlanguage() { - # Format: - # - expected - # - Title name - # - wgContLang (expected in most case) - # - wgLang (on some specific pages) - # - wgDefaultLanguageVariant - # - Optional message - return array( - array( 'fr', 'Main_page', 'fr', 'fr', false ), - array( 'es', 'Main_page', 'es', 'zh-tw', false ), - array( 'zh', 'Main_page', 'zh', 'zh-tw', false ), - - array( 'es', 'Main_page', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ), - array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ), - - array( 'zh-cn', 'Main_page', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ), - array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ), - array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ), - - array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ), - array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ), - - ); - } -} diff --git a/tests/phpunit/includes/UserTest.php b/tests/phpunit/includes/UserTest.php deleted file mode 100644 index 7a424aef..00000000 --- a/tests/phpunit/includes/UserTest.php +++ /dev/null @@ -1,171 +0,0 @@ -savedGroupPermissions = $GLOBALS['wgGroupPermissions']; - $this->savedRevokedPermissions = $GLOBALS['wgRevokePermissions']; - - $this->setUpPermissionGlobals(); - $this->setUpUser(); - } - private function setUpPermissionGlobals() { - global $wgGroupPermissions, $wgRevokePermissions; - - # Data for regular $wgGroupPermissions test - $wgGroupPermissions['unittesters'] = array( - 'test' => true, - 'runtest' => true, - 'writetest' => false, - 'nukeworld' => false, - ); - $wgGroupPermissions['testwriters'] = array( - 'test' => true, - 'writetest' => true, - 'modifytest' => true, - ); - # Data for regular $wgRevokePermissions test - $wgRevokePermissions['formertesters'] = array( - 'runtest' => true, - ); - } - private function setUpUser() { - $this->user = new User; - $this->user->addGroup( 'unittesters' ); - } - - public function tearDown() { - parent::tearDown(); - - $GLOBALS['wgGroupPermissions'] = $this->savedGroupPermissions; - $GLOBALS['wgRevokePermissions'] = $this->savedRevokedPermissions; - } - - public function testGroupPermissions() { - $rights = User::getGroupPermissions( array( 'unittesters' ) ); - $this->assertContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - - $rights = User::getGroupPermissions( array( 'unittesters', 'testwriters' ) ); - $this->assertContains( 'runtest', $rights ); - $this->assertContains( 'writetest', $rights ); - $this->assertContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - public function testRevokePermissions() { - $rights = User::getGroupPermissions( array( 'unittesters', 'formertesters' ) ); - $this->assertNotContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - public function testUserPermissions() { - $rights = $this->user->getRights(); - $this->assertContains( 'runtest', $rights ); - $this->assertNotContains( 'writetest', $rights ); - $this->assertNotContains( 'modifytest', $rights ); - $this->assertNotContains( 'nukeworld', $rights ); - } - - /** - * @dataProvider provideGetGroupsWithPermission - */ - public function testGetGroupsWithPermission( $expected, $right ) { - $result = User::getGroupsWithPermission( $right ); - sort( $result ); - sort( $expected ); - - $this->assertEquals( $expected, $result, "Groups with permission $right" ); - } - - public function provideGetGroupsWithPermission() { - return array( - array( - array( 'unittesters', 'testwriters' ), - 'test' - ), - array( - array( 'unittesters' ), - 'runtest' - ), - array( - array( 'testwriters' ), - 'writetest' - ), - array( - array( 'testwriters' ), - 'modifytest' - ), - ); - } - - /** - * @dataProvider provideUserNames - */ - public function testIsValidUserName( $username, $result, $message ) { - $this->assertEquals( $this->user->isValidUserName( $username ), $result, $message ); - } - - public function provideUserNames() { - return array( - array( '', false, 'Empty string' ), - array( ' ', false, 'Blank space' ), - array( 'abcd', false, 'Starts with small letter' ), - array( 'Ab/cd', false, 'Contains slash' ), - array( 'Ab cd' , true, 'Whitespace' ), - array( '192.168.1.1', false, 'IP' ), - array( 'User:Abcd', false, 'Reserved Namespace' ), - array( '12abcd232' , true , 'Starts with Numbers' ), - array( '?abcd' , true, 'Start with ? mark' ), - array( '#abcd', false, 'Start with #' ), - array( 'Abcdകഖഗഘ', true, ' Mixed scripts' ), - array( 'ജോസ്‌തോമസ്', false, 'ZWNJ- Format control character' ), - array( 'Ab cd', false, ' Ideographic space' ), - ); - } - - /** - * Test, if for all rights a right- message exist, - * which is used on Special:ListGroupRights as help text - * Extensions and core - */ - public function testAllRightsWithMessage() { - //Getting all user rights, for core: User::$mCoreRights, for extensions: $wgAvailableRights - $allRights = User::getAllRights(); - $allMessageKeys = Language::getMessageKeysFor( 'en' ); - - $rightsWithMessage = array(); - foreach ( $allMessageKeys as $message ) { - // === 0: must be at beginning of string (position 0) - if ( strpos( $message, 'right-' ) === 0 ) { - $rightsWithMessage[] = substr( $message, strlen( 'right-' ) ); - } - } - - sort( $allRights ); - sort( $rightsWithMessage ); - - $this->assertEquals( - $allRights, - $rightsWithMessage, - 'Each user rights (core/extensions) has a corresponding right- message.' - ); - } -} diff --git a/tests/phpunit/includes/WebRequestTest.php b/tests/phpunit/includes/WebRequestTest.php deleted file mode 100644 index 1fc0b4b3..00000000 --- a/tests/phpunit/includes/WebRequestTest.php +++ /dev/null @@ -1,216 +0,0 @@ -assertEquals( $expected, $result, $description ); - } - - function provideDetectServer() { - return array( - array( - 'http://x', - array( - 'HTTP_HOST' => 'x' - ), - 'Host header' - ), - array( - 'https://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'on', - ), - 'Host header with secure' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_PORT' => 80, - ), - 'Default SERVER_PORT', - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'HTTPS' => 'off', - ), - 'Secure off' - ), - array( - 'http://y', - array( - 'SERVER_NAME' => 'y', - ), - 'Server name' - ), - array( - 'http://x', - array( - 'HTTP_HOST' => 'x', - 'SERVER_NAME' => 'y', - ), - 'Host server name precedence' - ), - array( - 'http://[::1]:81', - array( - 'HTTP_HOST' => '[::1]', - 'SERVER_NAME' => '::1', - 'SERVER_PORT' => '81', - ), - 'Apache bug 26005' - ), - array( - 'http://localhost', - array( - 'SERVER_NAME' => '[2001' - ), - 'Kind of like lighttpd per commit message in MW r83847', - ), - array( - 'http://[2a01:e35:2eb4:1::2]:777', - array( - 'SERVER_NAME' => '[2a01:e35:2eb4:1::2]:777' - ), - 'Possible lighttpd environment per bug 14977 comment 13', - ), - ); - } - - /** - * @dataProvider provideGetIP - */ - function testGetIP( $expected, $input, $squid, $private, $description ) { - global $wgSquidServersNoPurge, $wgUsePrivateIPs; - $_SERVER = $input; - $wgSquidServersNoPurge = $squid; - $wgUsePrivateIPs = $private; - $request = new WebRequest(); - $result = $request->getIP(); - $this->assertEquals( $expected, $result, $description ); - } - - function provideGetIP() { - return array( - array( - '127.0.0.1', - array( - 'REMOTE_ADDR' => '127.0.0.1' - ), - array(), - false, - 'Simple IPv4' - ), - array( - '::1', - array( - 'REMOTE_ADDR' => '::1' - ), - array(), - false, - 'Simple IPv6' - ), - array( - '12.0.0.3', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array( '12.0.0.1', '12.0.0.2' ), - false, - 'With X-Forwaded-For' - ), - array( - '12.0.0.1', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array(), - false, - 'With X-Forwaded-For and disallowed server' - ), - array( - '12.0.0.2', - array( - 'REMOTE_ADDR' => '12.0.0.1', - 'HTTP_X_FORWARDED_FOR' => '12.0.0.3, 12.0.0.2' - ), - array( '12.0.0.1' ), - false, - 'With multiple X-Forwaded-For and only one allowed server' - ), - array( - '12.0.0.2', - array( - 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' - ), - array( '12.0.0.1', '12.0.0.2' ), - false, - 'With X-Forwaded-For and private IP' - ), - array( - '10.0.0.3', - array( - 'REMOTE_ADDR' => '12.0.0.2', - 'HTTP_X_FORWARDED_FOR' => '10.0.0.3, 12.0.0.2' - ), - array( '12.0.0.1', '12.0.0.2' ), - true, - 'With X-Forwaded-For and private IP (allowed)' - ), - ); - } - - /** - * @expectedException MWException - */ - function testGetIpLackOfRemoteAddrThrowAnException() { - $request = new WebRequest(); - # Next call throw an exception about lacking an IP - $request->getIP(); - } - - function languageProvider() { - return array( - array( '', array(), 'Empty Accept-Language header' ), - array( 'en', array( 'en' => 1 ), 'One language' ), - array( 'en, ar', array( 'en' => 1, 'ar' => 1 ), 'Two languages listed in appearance order.' ), - array( 'zh-cn,zh-tw', array( 'zh-cn' => 1, 'zh-tw' => 1 ), 'Two equally prefered languages, listed in appearance order per rfc3282. Checks c9119' ), - array( 'es, en; q=0.5', array( 'es' => 1, 'en' => '0.5' ), 'Spanish as first language and English and second' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Less prefered language first' ), - array( 'fr, en; q=0.5, es', array( 'fr' => 1, 'es' => 1, 'en' => '0.5' ), 'Three languages' ), - array( 'en; q=0.5, es', array( 'es' => 1, 'en' => '0.5' ), 'Two languages' ), - array( 'en, zh;q=0', array( 'en' => 1 ), "It's Chinese to me" ), - array( 'es; q=1, pt;q=0.7, it; q=0.6, de; q=0.1, ru;q=0', array( 'es' => '1', 'pt' => '0.7', 'it' => '0.6', 'de' => '0.1' ), 'Preference for romance languages' ), - array( 'en-gb, en-us; q=1', array( 'en-gb' => 1, 'en-us' => '1' ), 'Two equally prefered English variants' ), - ); - } - - /** - * @dataProvider languageProvider - */ - function testAcceptLang($acceptLanguageHeader, $expectedLanguages, $description) { - $_SERVER = array( 'HTTP_ACCEPT_LANGUAGE' => $acceptLanguageHeader ); - $request = new WebRequest(); - $this->assertSame( $request->getAcceptLang(), $expectedLanguages, $description); - } -} diff --git a/tests/phpunit/includes/WikiPageTest.php b/tests/phpunit/includes/WikiPageTest.php deleted file mode 100644 index 0e1e1ce8..00000000 --- a/tests/phpunit/includes/WikiPageTest.php +++ /dev/null @@ -1,784 +0,0 @@ -tablesUsed = array_merge ( $this->tablesUsed, - array( 'page', - 'revision', - 'text', - - 'recentchanges', - 'logging', - - 'page_props', - 'pagelinks', - 'categorylinks', - 'langlinks', - 'externallinks', - 'imagelinks', - 'templatelinks', - 'iwlinks' ) ); - } - - public function setUp() { - parent::setUp(); - $this->pages_to_delete = array(); - } - - public function tearDown() { - foreach ( $this->pages_to_delete as $p ) { - /* @var $p WikiPage */ - - try { - if ( $p->exists() ) { - $p->doDeleteArticle( "testing done." ); - } - } catch ( MWException $ex ) { - // fail silently - } - } - parent::tearDown(); - } - - protected function newPage( $title ) { - if ( is_string( $title ) ) $title = Title::newFromText( $title ); - - $p = new WikiPage( $title ); - - $this->pages_to_delete[] = $p; - - return $p; - } - - protected function createPage( $page, $text, $model = null ) { - if ( is_string( $page ) ) $page = Title::newFromText( $page ); - if ( $page instanceof Title ) $page = $this->newPage( $page ); - - $page->doEdit( $text, "testing", EDIT_NEW ); - - return $page; - } - - public function testDoEdit() { - $title = Title::newFromText( "WikiPageTest_testDoEdit" ); - - $page = $this->newPage( $title ); - - $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat."; - - $page->doEdit( $text, "testing 1" ); - - $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" ); - $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" ); - - $id = $page->getId(); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. " - . "Stet clita kasd [[gubergren]], no sea takimata sanctus est."; - - $page->doEdit( $text, "testing 2" ); - - # ------------------------ - $page = new WikiPage( $title ); - - $retrieved = $page->getText(); - $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' ); - } - - public function testDoQuickEdit() { - global $wgUser; - - $page = $this->createPage( "WikiPageTest_testDoQuickEdit", "original text" ); - - $text = "quick text"; - $page->doQuickEdit( $text, $wgUser, "testing q" ); - - # --------------------- - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $text, $page->getText() ); - } - - public function testDoDeleteArticle() { - $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo" ); - $id = $page->getId(); - - $page->doDeleteArticle( "testing deletion" ); - - $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" ); - $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" ); - - $t = Title::newFromText( $page->getTitle()->getPrefixedText() ); - $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); - } - - public function testDoDeleteUpdates() { - $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo" ); - $id = $page->getId(); - - $page->doDeleteUpdates( $id ); - - # ------------------------ - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) ); - $n = $res->numRows(); - $res->free(); - - $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' ); - } - - public function testGetRevision() { - $page = $this->newPage( "WikiPageTest_testGetRevision" ); - - $rev = $page->getRevision(); - $this->assertNull( $rev ); - - # ----------------- - $this->createPage( $page, "some text" ); - - $rev = $page->getRevision(); - - $this->assertEquals( $page->getLatest(), $rev->getId() ); - $this->assertEquals( "some text", $rev->getText() ); - } - - public function testGetText() { - $page = $this->newPage( "WikiPageTest_testGetText" ); - - $text = $page->getText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text" ); - - $text = $page->getText(); - $this->assertEquals( "some text", $text ); - } - - public function testGetRawText() { - $page = $this->newPage( "WikiPageTest_testGetRawText" ); - - $text = $page->getRawText(); - $this->assertFalse( $text ); - - # ----------------- - $this->createPage( $page, "some text" ); - - $text = $page->getRawText(); - $this->assertEquals( "some text", $text ); - } - - - public function testExists() { - $page = $this->newPage( "WikiPageTest_testExists" ); - $this->assertFalse( $page->exists() ); - - # ----------------- - $this->createPage( $page, "some text" ); - $this->assertTrue( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->exists() ); - - # ----------------- - $page->doDeleteArticle( "done testing" ); - $this->assertFalse( $page->exists() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertFalse( $page->exists() ); - } - - public function dataHasViewableContent() { - return array( - array( 'WikiPageTest_testHasViewableContent', false, true ), - array( 'Special:WikiPageTest_testHasViewableContent', false ), - array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ), - array( 'Special:Userlogin', true ), - array( 'MediaWiki:help', true ), - ); - } - - /** - * @dataProvider dataHasViewableContent - */ - public function testHasViewableContent( $title, $viewable, $create = false ) { - $page = $this->newPage( $title ); - $this->assertEquals( $viewable, $page->hasViewableContent() ); - - if ( $create ) { - $this->createPage( $page, "some text" ); - $this->assertTrue( $page->hasViewableContent() ); - - $page = new WikiPage( $page->getTitle() ); - $this->assertTrue( $page->hasViewableContent() ); - } - } - - public function dataGetRedirectTarget() { - return array( - array( 'WikiPageTest_testGetRedirectTarget_1', "hello world", null ), - array( 'WikiPageTest_testGetRedirectTarget_2', "#REDIRECT [[hello world]]", "Hello world" ), - ); - } - - /** - * @dataProvider dataGetRedirectTarget - */ - public function testGetRedirectTarget( $title, $text, $target ) { - $page = $this->createPage( $title, $text ); - - # now, test the actual redirect - $t = $page->getRedirectTarget(); - $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() ); - } - - /** - * @dataProvider dataGetRedirectTarget - */ - public function testIsRedirect( $title, $text, $target ) { - $page = $this->createPage( $title, $text ); - $this->assertEquals( !is_null( $target ), $page->isRedirect() ); - } - - public function dataIsCountable() { - return array( - - // any - array( 'WikiPageTest_testIsCountable', - '', - 'any', - true - ), - array( 'WikiPageTest_testIsCountable', - 'Foo', - 'any', - true - ), - - // comma - array( 'WikiPageTest_testIsCountable', - 'Foo', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - 'Foo, bar', - 'comma', - true - ), - - // link - array( 'WikiPageTest_testIsCountable', - 'Foo', - 'link', - false - ), - array( 'WikiPageTest_testIsCountable', - 'Foo [[bar]]', - 'link', - true - ), - - // redirects - array( 'WikiPageTest_testIsCountable', - '#REDIRECT [[bar]]', - 'any', - false - ), - array( 'WikiPageTest_testIsCountable', - '#REDIRECT [[bar]]', - 'comma', - false - ), - array( 'WikiPageTest_testIsCountable', - '#REDIRECT [[bar]]', - 'link', - false - ), - - // not a content namespace - array( 'Talk:WikiPageTest_testIsCountable', - 'Foo', - 'any', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - 'Foo, bar', - 'comma', - false - ), - array( 'Talk:WikiPageTest_testIsCountable', - 'Foo [[bar]]', - 'link', - false - ), - - // not a content namespace, different model - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - 'Foo', - 'any', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - 'Foo, bar', - 'comma', - false - ), - array( 'MediaWiki:WikiPageTest_testIsCountable.js', - 'Foo [[bar]]', - 'link', - false - ), - ); - } - - - /** - * @dataProvider dataIsCountable - */ - public function testIsCountable( $title, $text, $mode, $expected ) { - global $wgArticleCountMethod; - - $old = $wgArticleCountMethod; - $wgArticleCountMethod = $mode; - - $page = $this->createPage( $title, $text ); - $editInfo = $page->prepareTextForEdit( $page->getText() ); - - $v = $page->isCountable(); - $w = $page->isCountable( $editInfo ); - $wgArticleCountMethod = $old; - - $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - - $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true ) - . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" ); - } - - public function dataGetParserOutput() { - return array( - array("hello ''world''\n", "

    hello world

    "), - // @todo: more...? - ); - } - - /** - * @dataProvider dataGetParserOutput - */ - public function testGetParserOutput( $text, $expectedHtml ) { - $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text ); - - $opt = new ParserOptions(); - $po = $page->getParserOutput( $opt ); - $text = $po->getText(); - - $text = trim( preg_replace( '//sm', '', $text ) ); # strip injected comments - $text = preg_replace( '!\s*(

    )!sm', '\1', $text ); # don't let tidy confuse us - - $this->assertEquals( $expectedHtml, $text ); - return $po; - } - - static $sections = - - "Intro - -== stuff == -hello world - -== test == -just a test - -== foo == -more stuff -"; - - - public function dataReplaceSection() { - return array( - array( 'WikiPageTest_testReplaceSection', - WikiPageTest::$sections, - "0", - "No more", - null, - trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) ) - ), - array( 'WikiPageTest_testReplaceSection', - WikiPageTest::$sections, - "", - "No more", - null, - "No more" - ), - array( 'WikiPageTest_testReplaceSection', - WikiPageTest::$sections, - "2", - "== TEST ==\nmore fun", - null, - trim( preg_replace( '/^== test ==.*== foo ==/sm', "== TEST ==\nmore fun\n\n== foo ==", WikiPageTest::$sections ) ) - ), - array( 'WikiPageTest_testReplaceSection', - WikiPageTest::$sections, - "8", - "No more", - null, - trim( WikiPageTest::$sections ) - ), - array( 'WikiPageTest_testReplaceSection', - WikiPageTest::$sections, - "new", - "No more", - "New", - trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more" - ), - ); - } - - /** - * @dataProvider dataReplaceSection - */ - public function testReplaceSection( $title, $text, $section, $with, $sectionTitle, $expected ) { - $page = $this->createPage( $title, $text ); - $text = $page->replaceSection( $section, $with, $sectionTitle ); - $text = trim( $text ); - - $this->assertEquals( $expected, $text ); - } - - /* @todo FIXME: fix this! - public function testGetUndoText() { - global $wgDiff3; - - wfSuppressWarnings(); - $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 ); - wfRestoreWarnings(); - - if( !$haveDiff3 ) { - $this->markTestSkipped( "diff3 not installed or not found" ); - return; - } - - $text = "one"; - $page = $this->createPage( "WikiPageTest_testGetUndoText", $text ); - $rev1 = $page->getRevision(); - - $text .= "\n\ntwo"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two"); - $rev2 = $page->getRevision(); - - $text .= "\n\nthree"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three"); - $rev3 = $page->getRevision(); - - $text .= "\n\nfour"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four"); - $rev4 = $page->getRevision(); - - $text .= "\n\nfive"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five"); - $rev5 = $page->getRevision(); - - $text .= "\n\nsix"; - $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six"); - $rev6 = $page->getRevision(); - - $undo6 = $page->getUndoText( $rev6 ); - if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" ); - $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 ); - - $undo3 = $page->getUndoText( $rev4, $rev2 ); - if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" ); - $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 ); - - $undo2 = $page->getUndoText( $rev2 ); - if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" ); - $this->assertEquals( "one\n\nfive", $undo2 ); - } - */ - - /** - * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason. - */ - public function broken_testDoRollback() { - $admin = new User(); - $admin->setName("Admin"); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEdit( $text, "section one", EDIT_NEW, false, $admin ); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEdit( $text, "adding section two", 0, false, $user1 ); - - $user2 = new User(); - $user2->setName( "127.0.2.13" ); - $text .= "\n\nthree"; - $page = new WikiPage( $page->getTitle() ); - $page->doEdit( $text, "adding section three", 0, false, $user2 ); - - # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing - # or not committed under some circumstances. so, make sure the last revision has the right user name. - $dbr = wfGetDB( DB_SLAVE ); - $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) ); - - $page = new WikiPage( $page->getTitle() ); - $rev3 = $page->getRevision(); - $this->assertEquals( '127.0.2.13', $rev3->getUserText() ); - - $rev2 = $rev3->getPrevious(); - $this->assertEquals( '127.0.1.11', $rev2->getUserText() ); - - $rev1 = $rev2->getPrevious(); - $this->assertEquals( 'Admin', $rev1->getUserText() ); - - # now, try the actual rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null ); - $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision" ); - $this->assertEquals( "one\n\ntwo", $page->getText() ); - } - - /** - * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason. - */ - public function testDoRollback() { - $admin = new User(); - $admin->setName("Admin"); - - $text = "one"; - $page = $this->newPage( "WikiPageTest_testDoRollback" ); - $page->doEdit( $text, "section one", EDIT_NEW, false, $admin ); - $rev1 = $page->getRevision(); - - $user1 = new User(); - $user1->setName( "127.0.1.11" ); - $text .= "\n\ntwo"; - $page = new WikiPage( $page->getTitle() ); - $page->doEdit( $text, "adding section two", 0, false, $user1 ); - - # now, try the rollback - $admin->addGroup( "sysop" ); #XXX: make the test user a sysop... - $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null ); - $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin ); - - if ( $errors ) { - $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) ); - } - - $page = new WikiPage( $page->getTitle() ); - $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision" ); - $this->assertEquals( "one", $page->getText() ); - } - - public function dataGetAutosummary( ) { - return array( - array( - 'Hello there, world!', - '#REDIRECT [[Foo]]', - 0, - '/^Redirected page .*Foo/' - ), - - array( - null, - 'Hello world!', - EDIT_NEW, - '/^Created page .*Hello/' - ), - - array( - 'Hello there, world!', - '', - 0, - '/^Blanked/' - ), - - array( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut - labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et - ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'Hello world!', - 0, - '/^Replaced .*Hello/' - ), - - array( - 'foo', - 'bar', - 0, - '/^$/' - ), - ); - } - - /** - * @dataProvider dataGetAutoSummary - */ - public function testGetAutosummary( $old, $new, $flags, $expected ) { - $page = $this->newPage( "WikiPageTest_testGetAutosummary" ); - - $summary = $page->getAutosummary( $old, $new, $flags ); - - $this->assertTrue( (bool)preg_match( $expected, $summary ), "Autosummary didn't match expected pattern $expected: $summary" ); - } - - public function dataGetAutoDeleteReason( ) { - return array( - array( - array(), - false, - false - ), - - array( - array( - array( "first edit", null ), - ), - "/first edit.*only contributor/", - false - ), - - array( - array( - array( "first edit", null ), - array( "second edit", null ), - ), - "/second edit.*only contributor/", - true - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "second edit", "127.0.3.33" ), - ), - "/second edit/", - true - ), - - array( - array( - array( "first edit: " - . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " - . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. " - . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea " - . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ), - ), - '/first edit:.*\.\.\."/', - false - ), - - array( - array( - array( "first edit", "127.0.2.22" ), - array( "", "127.0.3.33" ), - ), - "/before blanking.*first edit/", - true - ), - - ); - } - - /** - * @dataProvider dataGetAutoDeleteReason - */ - public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) { - global $wgUser; - - $page = $this->newPage( "WikiPageTest_testGetAutoDeleteReason" ); - - $c = 1; - - foreach ( $edits as $edit ) { - $user = new User(); - - if ( !empty( $edit[1] ) ) $user->setName( $edit[1] ); - else $user = $wgUser; - - $page->doEdit( $edit[0], "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user ); - - $c += 1; - } - - $reason = $page->getAutoDeleteReason( $hasHistory ); - - if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason ); - else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ), "Autosummary didn't match expected pattern $expectedResult: $reason" ); - - $this->assertEquals( $expectedHistory, $hasHistory, "expected \$hasHistory to be " . var_export( $expectedHistory, true ) ); - - $page->doDeleteArticle( "done" ); - } - - public function dataPreSaveTransform() { - return array( - array( 'hello this is ~~~', - "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]", - ), - array( 'hello \'\'this\'\' is ~~~', - 'hello \'\'this\'\' is ~~~', - ), - ); - } - - /** - * @dataProvider dataPreSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - $this->hideDeprecated( 'WikiPage::preSaveTransform' ); - $user = new User(); - $user->setName("127.0.0.1"); - - $page = $this->newPage( "WikiPageTest_testPreloadTransform" ); - $text = $page->preSaveTransform( $text, $user ); - - $this->assertEquals( $expected, $text ); - } - -} - diff --git a/tests/phpunit/includes/XmlJsTest.php b/tests/phpunit/includes/XmlJsTest.php deleted file mode 100644 index c5b411fb..00000000 --- a/tests/phpunit/includes/XmlJsTest.php +++ /dev/null @@ -1,9 +0,0 @@ -assertNull( $obj->value ); - $obj = new XmlJsCode( '' ); - $this->assertSame( $obj->value, '' ); - } -} diff --git a/tests/phpunit/includes/XmlSelectTest.php b/tests/phpunit/includes/XmlSelectTest.php deleted file mode 100644 index 2407c151..00000000 --- a/tests/phpunit/includes/XmlSelectTest.php +++ /dev/null @@ -1,139 +0,0 @@ -select = new XmlSelect(); - } - protected function tearDown() { - $this->select = null; - } - - ### START OF TESTS ### - - public function testConstructWithoutParameters() { - $this->assertEquals( '', $this->select->getHTML() ); - } - - /** - * Parameters are $name (false), $id (false), $default (false) - * @dataProvider provideConstructionParameters - */ - public function testConstructParameters( $name, $id, $default, $expected ) { - $this->select = new XmlSelect( $name, $id, $default ); - $this->assertEquals( $expected, $this->select->getHTML() ); - } - - /** - * Provide parameters for testConstructParameters() which use three - * parameters: - * - $name (default: false) - * - $id (default: false) - * - $default (default: false) - * Provides a fourth parameters representing the expected HTML output - * - */ - public function provideConstructionParameters() { - return array( - /** - * Values are set following a 3-bit Gray code where two successive - * values differ by only one value. - * See http://en.wikipedia.org/wiki/Gray_code - */ - # $name $id $default - array( false , false, false, '' ), - array( false , false, 'foo', '' ), - array( false , 'id' , 'foo', '' ), - array( false , 'id' , false, '' ), - array( 'name', 'id' , false, '' ), - array( 'name', 'id' , 'foo', '' ), - array( 'name', false, 'foo', '' ), - array( 'name', false, false, '' ), - ); - } - - # Begin XmlSelect::addOption() similar to Xml::option - public function testAddOption() { - $this->select->addOption( 'foo' ); - $this->assertEquals( '', $this->select->getHTML() ); - } - public function testAddOptionWithDefault() { - $this->select->addOption( 'foo', true ); - $this->assertEquals( '', $this->select->getHTML() ); - } - public function testAddOptionWithFalse() { - $this->select->addOption( 'foo', false ); - $this->assertEquals( '', $this->select->getHTML() ); - } - public function testAddOptionWithValueZero() { - $this->select->addOption( 'foo', 0 ); - $this->assertEquals( '', $this->select->getHTML() ); - } - # End XmlSelect::addOption() similar to Xml::option - - public function testSetDefault() { - $this->select->setDefault( 'bar1' ); - $this->select->addOption( 'foo1' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->assertEquals( -'', $this->select->getHTML() ); - } - - /** - * Adding default later on should set the correct selection or - * raise an exception. - * To handle this, we need to render the options in getHtml() - */ - public function testSetDefaultAfterAddingOptions() { - $this->select->addOption( 'foo1' ); - $this->select->addOption( 'bar1' ); - $this->select->addOption( 'foo2' ); - $this->select->setDefault( 'bar1' ); # setting default after adding options - $this->assertEquals( -'', $this->select->getHTML() ); - } - - public function testGetAttributes() { - # create some attributes - $this->select->setAttribute( 'dummy', 0x777 ); - $this->select->setAttribute( 'string', 'euro €' ); - $this->select->setAttribute( 1911, 'razor' ); - - # verify we can retrieve them - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - $this->assertEquals( - $this->select->getAttribute( 'string' ), - 'euro €' - ); - $this->assertEquals( - $this->select->getAttribute( 1911 ), - 'razor' - ); - - # inexistant keys should give us 'null' - $this->assertEquals( - $this->select->getAttribute( 'I DO NOT EXIT' ), - null - ); - - # verify string / integer - $this->assertEquals( - $this->select->getAttribute( '1911' ), - 'razor' - ); - $this->assertEquals( - $this->select->getAttribute( 'dummy' ), - 0x777 - ); - } -} diff --git a/tests/phpunit/includes/XmlTest.php b/tests/phpunit/includes/XmlTest.php deleted file mode 100644 index 93ed3dc7..00000000 --- a/tests/phpunit/includes/XmlTest.php +++ /dev/null @@ -1,342 +0,0 @@ -getNamespaces(); - $wgContLang->setNamespaces( array( - -2 => 'Media', - -1 => 'Special', - 0 => '', - 1 => 'Talk', - 2 => 'User', - 3 => 'User_talk', - 4 => 'MyWiki', - 5 => 'MyWiki_Talk', - 6 => 'File', - 7 => 'File_talk', - 8 => 'MediaWiki', - 9 => 'MediaWiki_talk', - 10 => 'Template', - 11 => 'Template_talk', - 100 => 'Custom', - 101 => 'Custom_talk', - ) ); - } - - public function tearDown() { - global $wgLang, $wgContLang; - $wgLang = self::$oldLang; - - $wgContLang->setNamespaces( self::$oldNamespaces ); - } - - public function testExpandAttributes() { - $this->assertNull( Xml::expandAttributes(null), - 'Converting a null list of attributes' - ); - $this->assertEquals( '', Xml::expandAttributes( array() ), - 'Converting an empty list of attributes' - ); - } - - public function testExpandAttributesException() { - $this->setExpectedException('MWException'); - Xml::expandAttributes('string'); - } - - function testElementOpen() { - $this->assertEquals( - '', - Xml::element( 'element', null, null ), - 'Opening element with no attributes' - ); - } - - function testElementEmpty() { - $this->assertEquals( - '', - Xml::element( 'element', null, '' ), - 'Terminated empty element' - ); - } - - function testElementInputCanHaveAValueOfZero() { - $this->assertEquals( - '', - Xml::input( 'name', false, 0 ), - 'Input with a value of 0 (bug 23797)' - ); - } - function testElementEscaping() { - $this->assertEquals( - 'hello <there> you & you', - Xml::element( 'element', null, 'hello you & you' ), - 'Element with no attributes and content that needs escaping' - ); - } - - public function testEscapeTagsOnly() { - $this->assertEquals( '"><', Xml::escapeTagsOnly( '"><' ), - 'replace " > and < with their HTML entitites' - ); - } - - function testElementAttributes() { - $this->assertEquals( - '="<>">', - Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), - 'Element attributes, keys are not escaped' - ); - } - - function testOpenElement() { - $this->assertEquals( - '', - Xml::openElement( 'element', array( 'k' => 'v' ) ), - 'openElement() shortcut' - ); - } - - function testCloseElement() { - $this->assertEquals( '', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); - } - - /** - * @group Broken - */ - public function testDateMenu( ) { - $curYear = intval(gmdate('Y')); - $prevYear = $curYear - 1; - - $curMonth = intval(gmdate('n')); - $prevMonth = $curMonth - 1; - if( $prevMonth == 0 ) { $prevMonth = 12; } - $nextMonth = $curMonth + 1; - if( $nextMonth == 13 ) { $nextMonth = 1; } - - $this->assertEquals( - ' ', - Xml::dateMenu( 2011, 02 ), - "Date menu for february 2011" - ); - $this->assertEquals( - ' ', - Xml::dateMenu( 2011, -1), - "Date menu with negative month for 'All'" - ); - $this->assertEquals( - Xml::dateMenu( $curYear, $curMonth ), - Xml::dateMenu( '' , $curMonth ), - "Date menu year is the current one when not specified" - ); - - // @todo FIXME: next month can be in the next year - // test failing because it is now december - $this->assertEquals( - Xml::dateMenu( $prevYear, $nextMonth ), - Xml::dateMenu( '', $nextMonth ), - "Date menu next month is 11 months ago" - ); - - # @todo FIXME: Please note there is no year there! - $this->assertEquals( - ' ', - Xml::dateMenu( '', '' ), - "Date menu with neither year or month" - ); - } - - # - # textarea - # - function testTextareaNoContent() { - $this->assertEquals( - '', - Xml::textarea( 'name', '' ), - 'textarea() with not content' - ); - } - - function testTextareaAttribs() { - $this->assertEquals( - '', - Xml::textarea( 'name', '', 20, 10 ), - 'textarea() with custom attribs' - ); - } - - # - # input and label - # - function testLabelCreation() { - $this->assertEquals( - '', - Xml::label( 'name', 'id' ), - 'label() with no attribs' - ); - } - function testLabelAttributeCanOnlyBeClassOrTitle() { - $this->assertEquals( - '', - Xml::label( 'name', 'id', array( 'generated' => true ) ), - 'label() can not be given a generated attribute' - ); - $this->assertEquals( - '', - Xml::label( 'name', 'id', array( 'class' => 'nice' ) ), - 'label() can get a class attribute' - ); - $this->assertEquals( - '', - Xml::label( 'name', 'id', array( 'title' => 'nice tooltip' ) ), - 'label() can get a title attribute' - ); - $this->assertEquals( - '', - Xml::label( 'name', 'id', array( - 'generated' => true, - 'class' => 'nice', - 'title' => 'nice tooltip', - 'anotherattr' => 'value', - ) - ), - 'label() skip all attributes but "class" and "title"' - ); - } - - function testLanguageSelector() { - $select = Xml::languageSelector( 'en', true, null, - array( 'id' => 'testlang' ), wfMessage( 'yourlanguage' ) ); - $this->assertEquals( - '', - $select[0] - ); - } - - # - # JS - # - function testEscapeJsStringSpecialChars() { - $this->assertEquals( - '\\\\\r\n', - Xml::escapeJsString( "\\\r\n" ), - 'escapeJsString() with special characters' - ); - } - - function testEncodeJsVarBoolean() { - $this->assertEquals( - 'true', - Xml::encodeJsVar( true ), - 'encodeJsVar() with boolean' - ); - } - - function testEncodeJsVarNull() { - $this->assertEquals( - 'null', - Xml::encodeJsVar( null ), - 'encodeJsVar() with null' - ); - } - - function testEncodeJsVarArray() { - $this->assertEquals( - '["a",1]', - Xml::encodeJsVar( array( 'a', 1 ) ), - 'encodeJsVar() with array' - ); - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with associative array' - ); - } - - function testEncodeJsVarObject() { - $this->assertEquals( - '{"a":"a","b":1}', - Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with object' - ); - } - - function testEncodeJsVarInt() { - $this->assertEquals( - '123456', - Xml::encodeJsVar( 123456 ), - 'encodeJsVar() with int' - ); - } - - function testEncodeJsVarFloat() { - $this->assertEquals( - '1.23456', - Xml::encodeJsVar( 1.23456 ), - 'encodeJsVar() with float' - ); - } - - function testEncodeJsVarIntString() { - $this->assertEquals( - '"123456"', - Xml::encodeJsVar( '123456' ), - 'encodeJsVar() with int-like string' - ); - } - - function testEncodeJsVarFloatString() { - $this->assertEquals( - '"1.23456"', - Xml::encodeJsVar( '1.23456' ), - 'encodeJsVar() with float-like string' - ); - } -} diff --git a/tests/phpunit/includes/ZipDirectoryReaderTest.php b/tests/phpunit/includes/ZipDirectoryReaderTest.php deleted file mode 100644 index d90a6950..00000000 --- a/tests/phpunit/includes/ZipDirectoryReaderTest.php +++ /dev/null @@ -1,79 +0,0 @@ -zipDir = __DIR__ . '/../data/zip'; - } - - function zipCallback( $entry ) { - $this->entries[] = $entry; - } - - function readZipAssertError( $file, $error, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->hasMessage( $error ), $assertMessage ); - } - - function readZipAssertSuccess( $file, $assertMessage ) { - $this->entries = array(); - $status = ZipDirectoryReader::read( "{$this->zipDir}/$file", array( $this, 'zipCallback' ) ); - $this->assertTrue( $status->isOK(), $assertMessage ); - } - - function testEmpty() { - $this->readZipAssertSuccess( 'empty.zip', 'Empty zip' ); - } - - function testMultiDisk0() { - $this->readZipAssertError( 'split.zip', 'zip-unsupported', - 'Split zip error' ); - } - - function testNoSignature() { - $this->readZipAssertError( 'nosig.zip', 'zip-wrong-format', - 'No signature should give "wrong format" error' ); - } - - function testSimple() { - $this->readZipAssertSuccess( 'class.zip', 'Simple ZIP' ); - $this->assertEquals( $this->entries, array( array( - 'name' => 'Class.class', - 'mtime' => '20010115000000', - 'size' => 1, - ) ) ); - } - - function testBadCentralEntrySignature() { - $this->readZipAssertError( 'wrong-central-entry-sig.zip', 'zip-bad', - 'Bad central entry error' ); - } - - function testTrailingBytes() { - $this->readZipAssertError( 'trail.zip', 'zip-bad', - 'Trailing bytes error' ); - } - - function testWrongCDStart() { - $this->readZipAssertError( 'wrong-cd-start-disk.zip', 'zip-unsupported', - 'Wrong CD start disk error' ); - } - - - function testCentralDirectoryGap() { - $this->readZipAssertError( 'cd-gap.zip', 'zip-bad', - 'CD gap error' ); - } - - function testCentralDirectoryTruncated() { - $this->readZipAssertError( 'cd-truncated.zip', 'zip-bad', - 'CD truncated error (should hit unpack() overrun)' ); - } - - function testLooksLikeZip64() { - $this->readZipAssertError( 'looks-like-zip64.zip', 'zip-unsupported', - 'A file which looks like ZIP64 but isn\'t, should give error' ); - } -} diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php deleted file mode 100644 index 5dfceee8..00000000 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ /dev/null @@ -1,117 +0,0 @@ -doLogin(); - } - - function getTokens() { - return $this->getTokenList( self::$users['sysop'] ); - } - - function addDBData() { - $user = User::newFromName( 'UTApiBlockee' ); - - if ( $user->getId() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTApiBlockeePassword' ); - - $user->saveSettings(); - } - } - - /** - * This test has probably always been broken and use an invalid token - * Bug tracking brokenness is https://bugzilla.wikimedia.org/35646 - * - * Root cause is https://gerrit.wikimedia.org/r/3434 - * Which made the Block/Unblock API to actually verify the token - * previously always considered valid (bug 34212). - */ - function testMakeNormalBlock() { - - $data = $this->getTokens(); - - $user = User::newFromName( 'UTApiBlockee' ); - - if ( !$user->getId() ) { - $this->markTestIncomplete( "The user UTApiBlockee does not exist" ); - } - - if( !isset( $data[0]['query']['pages'] ) ) { - $this->markTestIncomplete( "No block token found" ); - } - - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( - 'action' => 'block', - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - 'token' => $pageinfo['blocktoken'] ), null, false, self::$users['sysop']->user ); - - $block = Block::newFromTarget('UTApiBlockee'); - - $this->assertTrue( !is_null( $block ), 'Block is valid' ); - - $this->assertEquals( 'UTApiBlockee', (string)$block->getTarget() ); - $this->assertEquals( 'Some reason', $block->mReason ); - $this->assertEquals( 'infinity', $block->mExpiry ); - - } - - /** - * @dataProvider provideBlockUnblockAction - */ - function testGetTokenUsingABlockingAction( $action ) { - $data = $this->doApiRequest( - array( - 'action' => $action, - 'user' => 'UTApiBlockee', - 'gettoken' => '' ), - null, - false, - self::$users['sysop']->user - ); - $this->assertEquals( 34, strlen( $data[0][$action]["{$action}token"] ) ); - } - - /** - * Attempting to block without a token should give a UsageException with - * error message: - * "The token parameter must be set" - * - * @dataProvider provideBlockUnblockAction - * @expectedException UsageException - */ - function testBlockingActionWithNoToken( $action ) { - $this->doApiRequest( - array( - 'action' => $action, - 'user' => 'UTApiBlockee', - 'reason' => 'Some reason', - ), - null, - false, - self::$users['sysop']->user - ); - } - - /** - * Just provide the 'block' and 'unblock' action to test both API calls - */ - function provideBlockUnblockAction() { - return array( - array( 'block' ), - array( 'unblock' ), - ); - } -} diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php deleted file mode 100644 index 5297d6da..00000000 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ /dev/null @@ -1,84 +0,0 @@ -doLogin(); - } - - function testEdit( ) { - $name = 'ApiEditPageTest_testEdit'; - - // -- test new page -------------------------------------------- - $apiResult = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', ) ); - $apiResult = $apiResult[0]; - - # Validate API result data - $this->assertArrayHasKey( 'edit', $apiResult ); - $this->assertArrayHasKey( 'result', $apiResult['edit'] ); - $this->assertEquals( 'Success', $apiResult['edit']['result'] ); - - $this->assertArrayHasKey( 'new', $apiResult['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $apiResult['edit'] ); - - $this->assertArrayHasKey( 'pageid', $apiResult['edit'] ); - - // -- test existing page, no change ---------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'some text', ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayHasKey( 'nochange', $data[0]['edit'] ); - - // -- test existing page, with change -------------------------- - $data = $this->doApiRequestWithToken( array( - 'action' => 'edit', - 'title' => $name, - 'text' => 'different text' ) ); - - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - $this->assertArrayNotHasKey( 'new', $data[0]['edit'] ); - $this->assertArrayNotHasKey( 'nochange', $data[0]['edit'] ); - - $this->assertArrayHasKey( 'oldrevid', $data[0]['edit'] ); - $this->assertArrayHasKey( 'newrevid', $data[0]['edit'] ); - $this->assertNotEquals( - $data[0]['edit']['newrevid'], - $data[0]['edit']['oldrevid'], - "revision id should change after edit" - ); - } - - function testEditAppend() { - $this->markTestIncomplete( "not yet implemented" ); - } - - function testEditSection() { - $this->markTestIncomplete( "not yet implemented" ); - } - - function testUndo() { - $this->markTestIncomplete( "not yet implemented" ); - } - - function testEditNonText() { - $this->markTestIncomplete( "not yet implemented" ); - } -} diff --git a/tests/phpunit/includes/api/ApiOptionsTest.php b/tests/phpunit/includes/api/ApiOptionsTest.php deleted file mode 100644 index 5243fca1..00000000 --- a/tests/phpunit/includes/api/ApiOptionsTest.php +++ /dev/null @@ -1,276 +0,0 @@ - 'success' ); - - function setUp() { - parent::setUp(); - - $this->mUserMock = $this->getMockBuilder( 'User' ) - ->disableOriginalConstructor() - ->getMock(); - - $this->mApiMainMock = $this->getMockBuilder( 'ApiBase' ) - ->disableOriginalConstructor() - ->getMock(); - - // Set up groups - $this->mUserMock->expects( $this->any() ) - ->method( 'getEffectiveGroups' )->will( $this->returnValue( array( '*', 'user')) ); - - // Create a new context - $this->mContext = new DerivativeContext( new RequestContext() ); - $this->mContext->getContext()->setTitle( Title::newFromText( 'Test' ) ); - $this->mContext->setUser( $this->mUserMock ); - - $this->mApiMainMock->expects( $this->any() ) - ->method( 'getContext' ) - ->will( $this->returnValue( $this->mContext ) ); - - $this->mApiMainMock->expects( $this->any() ) - ->method( 'getResult' ) - ->will( $this->returnValue( new ApiResult( $this->mApiMainMock ) ) ); - - - // Empty session - $this->mSession = array(); - - $this->mTested = new ApiOptions( $this->mApiMainMock, 'options' ); - - global $wgHooks; - if ( !isset( $wgHooks['GetPreferences'] ) ) { - $wgHooks['GetPreferences'] = array(); - } - $this->mOldGetPreferencesHooks = $wgHooks['GetPreferences']; - $wgHooks['GetPreferences'][] = array( $this, 'hookGetPreferences' ); - } - - public function tearDown() { - global $wgHooks; - - if ( $this->mOldGetPreferencesHooks !== false ) { - $wgHooks['GetPreferences'] = $this->mOldGetPreferencesHooks; - $this->mOldGetPreferencesHooks = false; - } - - parent::tearDown(); - } - - public function hookGetPreferences( $user, &$preferences ) { - foreach ( array( 'name', 'willBeNull', 'willBeEmpty', 'willBeHappy' ) as $k ) { - $preferences[$k] = array( - 'type' => 'text', - 'section' => 'test', - 'label' => ' ', - ); - } - - return true; - } - - private function getSampleRequest( $custom = array() ) { - $request = array( - 'token' => '123ABC', - 'change' => null, - 'optionname' => null, - 'optionvalue' => null, - ); - return array_merge( $request, $custom ); - } - - private function executeQuery( $request ) { - $this->mContext->setRequest( new FauxRequest( $request, true, $this->mSession ) ); - $this->mTested->execute(); - return $this->mTested->getResult()->getData(); - } - - /** - * @expectedException UsageException - */ - public function testNoToken() { - $request = $this->getSampleRequest( array( 'token' => null ) ); - - $this->executeQuery( $request ); - } - - public function testAnon() { - $this->mUserMock->expects( $this->once() ) - ->method( 'isAnon' ) - ->will( $this->returnValue( true ) ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'notloggedin', $e->getCodeString() ); - $this->assertEquals( 'Anonymous users cannot change preferences', $e->getMessage() ); - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testNoOptionname() { - try { - $request = $this->getSampleRequest( array( 'optionvalue' => '1' ) ); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'nooptionname', $e->getCodeString() ); - $this->assertEquals( 'The optionname parameter must be set', $e->getMessage() ); - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testNoChanges() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'saveSettings' ); - - try { - $request = $this->getSampleRequest(); - - $this->executeQuery( $request ); - } catch ( UsageException $e ) { - $this->assertEquals( 'nochanges', $e->getCodeString() ); - $this->assertEquals( 'No changes were requested', $e->getMessage() ); - return; - } - $this->fail( "UsageException was not thrown" ); - } - - public function testReset() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->never() ) - ->method( 'setOption' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'reset' => '' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionWithValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name', 'optionvalue' => 'value' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testOptionResetValue() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( null ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'optionname' => 'name' ) ); - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testChange() { - $this->mUserMock->expects( $this->never() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 1 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 2 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeNull' ), $this->equalTo( null ) ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeEmpty' ), $this->equalTo( '' ) ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 6 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $request = $this->getSampleRequest( array( 'change' => 'willBeNull|willBeEmpty=|willBeHappy=Happy' ) ); - - $response = $this->executeQuery( $request ); - - $this->assertEquals( self::$Success, $response ); - } - - public function testResetChangeOption() { - $this->mUserMock->expects( $this->once() ) - ->method( 'resetOptions' ); - - $this->mUserMock->expects( $this->at( 2 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 3 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'willBeHappy' ), $this->equalTo( 'Happy' ) ); - - $this->mUserMock->expects( $this->at( 4 ) ) - ->method( 'getOptions' ); - - $this->mUserMock->expects( $this->at( 5 ) ) - ->method( 'setOption' ) - ->with( $this->equalTo( 'name' ), $this->equalTo( 'value' ) ); - - $this->mUserMock->expects( $this->once() ) - ->method( 'saveSettings' ); - - $args = array( - 'reset' => '', - 'change' => 'willBeHappy=Happy', - 'optionname' => 'name', - 'optionvalue' => 'value' - ); - - $response = $this->executeQuery( $this->getSampleRequest( $args ) ); - - $this->assertEquals( self::$Success, $response ); - } -} diff --git a/tests/phpunit/includes/api/ApiPurgeTest.php b/tests/phpunit/includes/api/ApiPurgeTest.php deleted file mode 100644 index 2566c6cd..00000000 --- a/tests/phpunit/includes/api/ApiPurgeTest.php +++ /dev/null @@ -1,40 +0,0 @@ -doLogin(); - } - - /** - * @group Broken - */ - function testPurgeMainPage() { - if ( !Title::newFromText( 'UTPage' )->exists() ) { - $this->markTestIncomplete( "The article [[UTPage]] does not exist" ); - } - - $somePage = mt_rand(); - - $data = $this->doApiRequest( array( - 'action' => 'purge', - 'titles' => 'UTPage|' . $somePage . '|%5D' ) ); - - $this->assertArrayHasKey( 'purge', $data[0], - "Must receive a 'purge' result from API" ); - - $this->assertEquals( 3, count( $data[0]['purge'] ), - "Purge request for three articles should give back three results received: " . var_export( $data[0]['purge'], true ) ); - - $pages = array( 'UTPage' => 'purged', $somePage => 'missing', '%5D' => 'invalid' ); - foreach( $data[0]['purge'] as $v ) { - $this->assertArrayHasKey( $pages[$v['title']], $v ); - } - } - -} diff --git a/tests/phpunit/includes/api/ApiQueryTest.php b/tests/phpunit/includes/api/ApiQueryTest.php deleted file mode 100644 index a4b9dc70..00000000 --- a/tests/phpunit/includes/api/ApiQueryTest.php +++ /dev/null @@ -1,68 +0,0 @@ -doLogin(); - } - - function testTitlesGetNormalized() { - - global $wgMetaNamespace; - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Project:articleA|article_B' ) ); - - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'normalized', $data[0]['query'] ); - - // Forge a normalized title - $to = Title::newFromText( $wgMetaNamespace.':ArticleA' ); - - $this->assertEquals( - array( - 'from' => 'Project:articleA', - 'to' => $to->getPrefixedText(), - ), - $data[0]['query']['normalized'][0] - ); - - $this->assertEquals( - array( - 'from' => 'article_B', - 'to' => 'Article B' - ), - $data[0]['query']['normalized'][1] - ); - - } - - function testTitlesAreRejectedIfInvalid() { - $title = false; - while( !$title || Title::newFromText( $title )->exists() ) { - $title = md5( mt_rand( 0, 10000 ) + rand( 0, 999000 ) ); - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => $title . '|Talk:' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $this->assertEquals( 2, count( $data[0]['query']['pages'] ) ); - - $this->assertArrayHasKey( -2, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( -1, $data[0]['query']['pages'] ); - - $this->assertArrayHasKey( 'missing', $data[0]['query']['pages'][-2] ); - $this->assertArrayHasKey( 'invalid', $data[0]['query']['pages'][-1] ); - } - -} diff --git a/tests/phpunit/includes/api/ApiTest.php b/tests/phpunit/includes/api/ApiTest.php deleted file mode 100644 index c3eacd5b..00000000 --- a/tests/phpunit/includes/api/ApiTest.php +++ /dev/null @@ -1,280 +0,0 @@ -assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => false ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - function testRequireOnlyOneParameterZero() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => 0 ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - function testRequireOnlyOneParameterTrue() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => true ), "filename", "enablechunks" ) ); - } - - /** - * Test that the API will accept a FauxRequest and execute. The help action - * (default) throws a UsageException. Just validate we're getting proper XML - * - * @expectedException UsageException - */ - function testApi() { - - $api = new ApiMain( - new FauxRequest( array( 'action' => 'help', 'format' => 'xml' ) ) - ); - $api->execute(); - $api->getPrinter()->setBufferResult( true ); - $api->printResult( false ); - $resp = $api->getPrinter()->getBuffer(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - } - - /** - * Test result of attempted login with an empty username - */ - function testApiLoginNoName() { - $data = $this->doApiRequest( array( 'action' => 'login', - 'lgname' => '', 'lgpassword' => self::$users['sysop']->password, - ) ); - $this->assertEquals( 'NoName', $data[0]['login']['result'] ); - } - - function testApiLoginBadPass() { - global $wgServer; - - $user = self::$users['sysop']; - $user->user->logOut(); - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => "bad", - ) - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => "badnowayinhell", - ), $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "WrongPass", $a ); - } - - function testApiLoginGoodPass() { - global $wgServer; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $user = self::$users['sysop']; - $user->user->logOut(); - - $ret = $this->doApiRequest( array( - "action" => "login", - "lgname" => $user->username, - "lgpassword" => $user->password, - ) - ); - - $result = $ret[0]; - $this->assertNotInternalType( "bool", $result ); - $this->assertNotInternalType( "null", $result["login"] ); - - $a = $result["login"]["result"]; - $this->assertEquals( "NeedToken", $a ); - $token = $result["login"]["token"]; - - $ret = $this->doApiRequest( array( - "action" => "login", - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password, - ), $ret[2] - ); - - $result = $ret[0]; - - $this->assertNotInternalType( "bool", $result ); - $a = $result["login"]["result"]; - - $this->assertEquals( "Success", $a ); - } - - /** - * @group Broken - */ - function testApiGotCookie() { - $this->markTestIncomplete( "The server can't do external HTTP requests, and the internal one won't give cookies" ); - - global $wgServer, $wgScriptPath; - - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - $user = self::$users['sysop']; - - $req = MWHttpRequest::factory( self::$apiUrl . "?action=login&format=xml", - array( "method" => "POST", - "postData" => array( - "lgname" => $user->username, - "lgpassword" => $user->password ) ) ); - $req->execute(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotInternalType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $this->assertNotInternalType( "null", $sxe->login[0] ); - - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - $token = (string)$sxe->login[0]->attributes()->token; - - $req->setData( array( - "lgtoken" => $token, - "lgname" => $user->username, - "lgpassword" => $user->password ) ); - $req->execute(); - - $cj = $req->getCookieJar(); - $serverName = parse_url( $wgServer, PHP_URL_HOST ); - $this->assertNotEquals( false, $serverName ); - $serializedCookie = $cj->serializeToHttpRequest( $wgScriptPath, $serverName ); - $this->assertNotEquals( '', $serializedCookie ); - $this->assertRegexp( '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . $user->userName . '; .*Token=/', $serializedCookie ); - - return $cj; - } - - /** - * @todo Finish filling me out...what are we trying to test here? - */ - function testApiListPages() { - global $wgServer; - if ( !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServer to be set in LocalSettings.php' ); - } - - $ret = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => 'Main Page', - 'rvprop' => 'timestamp|user|comment|content', - ) ); - - $result = $ret[0]['query']['pages']; - $this->markTestIncomplete( "Somebody needs to finish loving me" ); - } - - function testRunLogin() { - $sysopUser = self::$users['sysop']; - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $sysopUser->username, - 'lgpassword' => $sysopUser->password ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - "lgname" => $sysopUser->username, - "lgpassword" => $sysopUser->password ), $data[2] ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - function testGettingToken() { - foreach ( self::$users as $user ) { - $this->runTokenTest( $user ); - } - } - - function runTokenTest( $user ) { - - $data = $this->getTokenList( $user ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - - $rights = $user->user->getRights(); - - $this->assertArrayHasKey( $key, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( 'edittoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'movetoken', $data[0]['query']['pages'][$key] ); - - if ( isset( $rights['delete'] ) ) { - $this->assertArrayHasKey( 'deletetoken', $data[0]['query']['pages'][$key] ); - } - - if ( isset( $rights['block'] ) ) { - $this->assertArrayHasKey( 'blocktoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'unblocktoken', $data[0]['query']['pages'][$key] ); - } - - if ( isset( $rights['protect'] ) ) { - $this->assertArrayHasKey( 'protecttoken', $data[0]['query']['pages'][$key] ); - } - - return $data; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCase.php b/tests/phpunit/includes/api/ApiTestCase.php deleted file mode 100644 index b84292e3..00000000 --- a/tests/phpunit/includes/api/ApiTestCase.php +++ /dev/null @@ -1,187 +0,0 @@ - new TestUser( - 'Apitestsysop', - 'Api Test Sysop', - 'api_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Apitestuser', - 'Api Test User', - 'api_test_user@example.com', - array() - ) - ); - - $wgUser = self::$users['sysop']->user; - - $this->apiContext = new ApiTestContext(); - - } - - protected function doApiRequest( Array $params, Array $session = null, $appendModule = false, User $user = null ) { - global $wgRequest, $wgUser; - - if ( is_null( $session ) ) { - # re-use existing global session by default - $session = $wgRequest->getSessionArray(); - } - - # set up global environment - if ( $user ) { - $wgUser = $user; - } - - $wgRequest = new FauxRequest( $params, true, $session ); - RequestContext::getMain()->setRequest( $wgRequest ); - - # set up local environment - $context = $this->apiContext->newTestContext( $wgRequest, $wgUser ); - - $module = new ApiMain( $context, true ); - - # run it! - $module->execute(); - - # construct result - $results = array( - $module->getResultData(), - $context->getRequest(), - $context->getRequest()->getSessionArray() - ); - if( $appendModule ) { - $results[] = $module; - } - - return $results; - } - - /** - * Add an edit token to the API request - * This is cheating a bit -- we grab a token in the correct format and then add it to the pseudo-session and to the - * request, without actually requesting a "real" edit token - * @param $params Array: key-value API params - * @param $session Array|null: session array - * @param $user User|null A User object for the context - */ - protected function doApiRequestWithToken( Array $params, Array $session = null, User $user = null ) { - global $wgRequest; - - if ( $session === null ) { - $session = $wgRequest->getSessionArray(); - } - - if ( $session['wsToken'] ) { - // add edit token to fake session - $session['wsEditToken'] = $session['wsToken']; - // add token to request parameters - $params['token'] = md5( $session['wsToken'] ) . User::EDIT_TOKEN_SUFFIX; - return $this->doApiRequest( $params, $session, false, $user ); - } else { - throw new Exception( "request data not in right format" ); - } - } - - protected function doLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password ) ); - - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => self::$users['sysop']->username, - 'lgpassword' => self::$users['sysop']->password - ), $data[2] ); - - return $data; - } - - protected function getTokenList( $user, $session = null ) { - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Main Page', - 'intoken' => 'edit|delete|protect|move|block|unblock|watch', - 'prop' => 'info' ), $session, false, $user->user ); - return $data; - } -} - -class UserWrapper { - public $userName, $password, $user; - - public function __construct( $userName, $password, $group = '' ) { - $this->userName = $userName; - $this->password = $password; - - $this->user = User::newFromName( $this->userName ); - if ( !$this->user->getID() ) { - $this->user = User::createNew( $this->userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - } - $this->user->setPassword( $this->password ); - - if ( $group !== '' ) { - $this->user->addGroup( $group ); - } - $this->user->saveSettings(); - } -} - -class MockApi extends ApiBase { - public function execute() { } - public function getVersion() { } - - public function __construct() { } - - public function getAllowedParams() { - return array( - 'filename' => null, - 'enablechunks' => false, - 'sessionkey' => null, - ); - } -} - -class ApiTestContext extends RequestContext { - - /** - * Returns a DerivativeContext with the request variables in place - * - * @param $request WebRequest request object including parameters and session - * @param $user User or null - * @return DerivativeContext - */ - public function newTestContext( WebRequest $request, User $user = null ) { - $context = new DerivativeContext( $this ); - $context->setRequest( $request ); - if ( $user !== null ) { - $context->setUser( $user ); - } - return $context; - } -} diff --git a/tests/phpunit/includes/api/ApiTestCaseUpload.php b/tests/phpunit/includes/api/ApiTestCaseUpload.php deleted file mode 100644 index 39c79547..00000000 --- a/tests/phpunit/includes/api/ApiTestCaseUpload.php +++ /dev/null @@ -1,148 +0,0 @@ -clearFakeUploads(); - } - - public function tearDown() { - $this->clearTempUpload(); - } - - /** - * Helper function -- remove files and associated articles by Title - * @param $title Title: title to be removed - */ - public function deleteFileByTitle( $title ) { - if ( $title->exists() ) { - $file = wfFindFile( $title, array( 'ignoreRedirect' => true ) ); - $noOldArchive = ""; // yes this really needs to be set this way - $comment = "removing for test"; - $restrictDeletedVersions = false; - $status = FileDeleteForm::doDelete( $title, $file, $noOldArchive, $comment, $restrictDeletedVersions ); - if ( !$status->isGood() ) { - return false; - } - $page = WikiPage::factory( $title ); - $page->doDeleteArticle( "removing for test" ); - - // see if it now doesn't exist; reload - $title = Title::newFromText( $title->getText(), NS_FILE ); - } - return ! ( $title && $title instanceof Title && $title->exists() ); - } - - /** - * Helper function -- remove files and associated articles with a particular filename - * @param $fileName String: filename to be removed - */ - public function deleteFileByFileName( $fileName ) { - return $this->deleteFileByTitle( Title::newFromText( $fileName, NS_FILE ) ); - } - - - /** - * Helper function -- given a file on the filesystem, find matching content in the db (and associated articles) and remove them. - * @param $filePath String: path to file on the filesystem - */ - public function deleteFileByContent( $filePath ) { - $hash = FSFile::getSha1Base36FromPath( $filePath ); - $dupes = RepoGroup::singleton()->findBySha1( $hash ); - $success = true; - foreach ( $dupes as $dupe ) { - $success &= $this->deleteFileByTitle( $dupe->getTitle() ); - } - return $success; - } - - /** - * Fake an upload by dumping the file into temp space, and adding info to $_FILES. - * (This is what PHP would normally do). - * @param $fieldName String: name this would have in the upload form - * @param $fileName String: name to title this - * @param $type String: mime type - * @param $filePath String: path where to find file contents - */ - function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) { - $tmpName = tempnam( wfTempDir(), "" ); - if ( !file_exists( $filePath ) ) { - throw new Exception( "$filePath doesn't exist!" ); - }; - - if ( !copy( $filePath, $tmpName ) ) { - throw new Exception( "couldn't copy $filePath to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[ $fieldName ] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - - return true; - - } - function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ){ - $tmpName = tempnam( wfTempDir(), "" ); - // copy the chunk data to temp location: - if ( !file_put_contents( $tmpName, $chunkData ) ) { - throw new Exception( "couldn't copy chunk data to $tmpName" ); - } - - clearstatcache(); - $size = filesize( $tmpName ); - if ( $size === false ) { - throw new Exception( "couldn't stat $tmpName" ); - } - - $_FILES[ $fieldName ] = array( - 'name' => $fileName, - 'type' => $type, - 'tmp_name' => $tmpName, - 'size' => $size, - 'error' => null - ); - } - - function clearTempUpload() { - if( isset( $_FILES['file']['tmp_name'] ) ) { - $tmp = $_FILES['file']['tmp_name']; - if( file_exists( $tmp ) ) { - unlink( $tmp ); - } - } - } - - /** - * Remove traces of previous fake uploads - */ - function clearFakeUploads() { - $_FILES = array(); - } - - - - -} diff --git a/tests/phpunit/includes/api/ApiUploadTest.php b/tests/phpunit/includes/api/ApiUploadTest.php deleted file mode 100644 index 642fed05..00000000 --- a/tests/phpunit/includes/api/ApiUploadTest.php +++ /dev/null @@ -1,569 +0,0 @@ - 'login', - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "NeedToken", $result['login']['result'] ); - $token = $result['login']['token']; - - $params = array( - 'action' => 'login', - 'lgtoken' => $token, - 'lgname' => $user->username, - 'lgpassword' => $user->password - ); - list( $result, , $session ) = $this->doApiRequest( $params, $session ); - $this->assertArrayHasKey( "login", $result ); - $this->assertArrayHasKey( "result", $result['login'] ); - $this->assertEquals( "Success", $result['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $result['login'] ); - - $this->assertNotEmpty( $session, 'API Login must return a session' ); - return $session; - - } - - /** - * @depends testLogin - */ - public function testUploadRequiresToken( $session ) { - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload' - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - /** - * @depends testLogin - */ - public function testUploadMissingParams( $session ) { - $exception = false; - try { - $this->doApiRequestWithToken( array( - 'action' => 'upload', - ), $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters filekey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - } - - - /** - * @depends testLogin - */ - public function testUpload( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } - catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - - if (! $this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadZeroLength( $session ) { - $mimeType = 'image/png'; - - $filePath = tempnam( wfTempDir(), "" ); - $fileName = "apiTestUploadZeroLength.png"; - - $this->deleteFileByFileName( $fileName ); - - if (! $this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - $this->doApiRequestWithToken( $params, $session, self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $this->assertContains( 'The file you submitted was empty', $e->getMessage() ); - $exception = true; - } - $this->assertTrue( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameFileName( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() ); - } - catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - // we'll reuse this filename - $fileName = basename( $filePaths[0] ); - - // clear any other files with the same name - $this->deleteFileByFileName( $fileName ); - - // we reuse these params - $params = array( - 'action' => 'upload', - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - // first upload .... should succeed - - if (! $this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // second upload with the same name (but different content) - - if (! $this->fakeUploadFile( 'file', $fileName, $mimeType, $filePaths[1] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, , ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['exists'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePaths[0] ); - unlink( $filePaths[1] ); - } - - - /** - * @depends testLogin - */ - public function testUploadSameContent( $session ) { - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } - catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileNames[0] = basename( $filePaths[0] ); - $fileNames[1] = "SameContentAs" . $fileNames[0]; - - // clear any other files with the same name or content - $this->deleteFileByContent( $filePaths[0] ); - $this->deleteFileByFileName( $fileNames[0] ); - $this->deleteFileByFileName( $fileNames[1] ); - - // first upload .... should succeed - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[0], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[0], - ); - - if (! $this->fakeUploadFile( 'file', $fileNames[0], $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $exception = false; - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - - // second upload with the same content (but different name) - - if (! $this->fakeUploadFile( 'file', $fileNames[1], $mimeType, $filePaths[0] ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'filename' => $fileNames[1], - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for " . $fileNames[1], - ); - - $exception = false; - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Warning', $result['upload']['result'] ); - $this->assertTrue( isset( $result['upload']['warnings'] ) ); - $this->assertTrue( isset( $result['upload']['warnings']['duplicate'] ) ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileNames[0] ); - $this->deleteFileByFilename( $fileNames[1] ); - unlink( $filePaths[0] ); - } - - - /** - * @depends testLogin - */ - public function testUploadStash( $session ) { - global $wgUser; - $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere - - $extension = 'png'; - $mimeType = 'image/png'; - - try { - $randomImageGenerator = new RandomImageGenerator(); - $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() ); - } - catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $filePath = $filePaths[0]; - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - if (! $this->fakeUploadFile( 'file', $fileName, $mimeType, $filePath ) ) { - $this->markTestIncomplete( "Couldn't upload file!\n" ); - } - - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'file' => 'dummy content', - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName", - ); - - $exception = false; - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); // FIXME: leaks a temporary file - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertFalse( $exception ); - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertEquals( $fileSize, ( int )$result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - $this->assertEquals( $result['upload']['sessionkey'], $result['upload']['filekey'] ); - $filekey = $result['upload']['filekey']; - - // it should be visible from Special:UploadStash - // XXX ...but how to test this, with a fake WebRequest with the session? - - // now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - - $this->clearFakeUploads(); - $exception = false; - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception, "No UsageException exception." ); - - // clean up - $this->deleteFileByFilename( $fileName ); - unlink( $filePath ); - } - - - /** - * @depends testLogin - */ - public function testUploadChunks( $session ) { - global $wgUser; - $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere - - $chunkSize = 1048576; - // Download a large image file - // ( using RandomImageGenerator for large files is not stable ) - $mimeType = 'image/jpeg'; - $url = 'http://upload.wikimedia.org/wikipedia/commons/e/ed/Oberaargletscher_from_Oberaar%2C_2010_07.JPG'; - $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg'; - try { - // Only download if the file is not avaliable in the temp location: - if( !is_file( $filePath ) ){ - copy($url, $filePath); - } - } - catch ( Exception $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - - $fileSize = filesize( $filePath ); - $fileName = basename( $filePath ); - - $this->deleteFileByFileName( $fileName ); - $this->deleteFileByContent( $filePath ); - - // Base upload params: - $params = array( - 'action' => 'upload', - 'stash' => 1, - 'filename' => $fileName, - 'filesize' => $fileSize, - 'offset' => 0, - ); - - // Upload chunks - $chunkSessionKey = false; - $resultOffset = 0; - // Open the file: - $handle = @fopen ($filePath, "r"); - if( $handle === false ){ - $this->markTestIncomplete( "could not open file: $filePath" ); - } - while (!feof ($handle)) { - // Get the current chunk - $chunkData = @fread( $handle, $chunkSize ); - - // Upload the current chunk into the $_FILE object: - $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData ); - - // Check for chunkSessionKey - if( !$chunkSessionKey ){ - // Upload fist chunk ( and get the session key ) - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - // Make sure we got a valid chunk continue: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - // If we don't get a session key mark test incomplete. - if( ! isset( $result['upload']['filekey'] ) ){ - $this->markTestIncomplete( "no filekey provided" ); - } - $chunkSessionKey = $result['upload']['filekey']; - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // First chunk should have chunkSize == offset - $this->assertEquals( $chunkSize, $result['upload']['offset'] ); - $resultOffset = $result['upload']['offset']; - continue; - } - // Filekey set to chunk session - $params['filekey'] = $chunkSessionKey; - // Update the offset ( always add chunkSize for subquent chunks should be in-sync with $result['upload']['offset'] ) - $params['offset'] += $chunkSize; - // Make sure param offset is insync with resultOffset: - $this->assertEquals( $resultOffset, $params['offset'] ); - // Upload current chunk - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $this->markTestIncomplete( $e->getMessage() ); - } - // Make sure we got a valid chunk continue: - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - - // Check if we were on the last chunk: - if( $params['offset'] + $chunkSize >= $fileSize ){ - $this->assertEquals( 'Success', $result['upload']['result'] ); - break; - } else { - $this->assertEquals( 'Continue', $result['upload']['result'] ); - // update $resultOffset - $resultOffset = $result['upload']['offset']; - } - } - fclose ($handle); - - // Check that we got a valid file result: - wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n"); - $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] ); - $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] ); - $this->assertTrue( isset( $result['upload']['filekey'] ) ); - $filekey = $result['upload']['filekey']; - - // Now we should try to release the file from stash - $params = array( - 'action' => 'upload', - 'filekey' => $filekey, - 'filename' => $fileName, - 'comment' => 'dummy comment', - 'text' => "This is the page text for $fileName, altered", - ); - $this->clearFakeUploads(); - $exception = false; - try { - list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session, - self::$users['uploader']->user ); - } catch ( UsageException $e ) { - $exception = true; - } - $this->assertTrue( isset( $result['upload'] ) ); - $this->assertEquals( 'Success', $result['upload']['result'] ); - $this->assertFalse( $exception ); - - // clean up - $this->deleteFileByFilename( $fileName ); - // don't remove downloaded temporary file for fast subquent tests. - //unlink( $filePath ); - } -} diff --git a/tests/phpunit/includes/api/ApiWatchTest.php b/tests/phpunit/includes/api/ApiWatchTest.php deleted file mode 100644 index d2e98152..00000000 --- a/tests/phpunit/includes/api/ApiWatchTest.php +++ /dev/null @@ -1,176 +0,0 @@ -doLogin(); - } - - function getTokens() { - $data = $this->getTokenList( self::$users['sysop'] ); - - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - - return $pageinfo; - } - - /** - */ - function testWatchEdit() { - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'edit', - 'title' => 'UTPage', - 'text' => 'new text', - 'token' => $pageinfo['edittoken'], - 'watchlist' => 'watch' ) ); - $this->assertArrayHasKey( 'edit', $data[0] ); - $this->assertArrayHasKey( 'result', $data[0]['edit'] ); - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - return $data; - } - - /** - * @depends testWatchEdit - */ - function testWatchClear() { - - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - if ( isset( $data[0]['query']['watchlist'] ) ) { - $wl = $data[0]['query']['watchlist']; - - foreach ( $wl as $page ) { - $data = $this->doApiRequest( array( - 'action' => 'watch', - 'title' => $page['title'], - 'unwatch' => true, - 'token' => $pageinfo['watchtoken'] ) ); - } - } - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'watchlist', $data[0]['query'] ); - $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) ); - - return $data; - } - - /** - */ - function testWatchProtect() { - - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'protect', - 'token' => $pageinfo['protecttoken'], - 'title' => 'UTPage', - 'protections' => 'edit=sysop', - 'watchlist' => 'unwatch' ) ); - - $this->assertArrayHasKey( 'protect', $data[0] ); - $this->assertArrayHasKey( 'protections', $data[0]['protect'] ); - $this->assertEquals( 1, count( $data[0]['protect']['protections'] ) ); - $this->assertArrayHasKey( 'edit', $data[0]['protect']['protections'][0] ); - } - - /** - */ - function testGetRollbackToken() { - - $pageinfo = $this->getTokens(); - - if ( !Title::newFromText( 'UTPage' )->exists() ) { - $this->markTestSkipped( "The article [[UTPage]] does not exist" ); //TODO: just create it? - } - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => 'UTPage', - 'rvtoken' => 'rollback' ) ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - - if ( isset( $data[0]['query']['pages'][$key]['missing'] ) ) { - $this->markTestSkipped( "Target page (UTPage) doesn't exist" ); - } - - $this->assertArrayHasKey( 'pageid', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'revisions', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 0, $data[0]['query']['pages'][$key]['revisions'] ); - $this->assertArrayHasKey( 'rollbacktoken', $data[0]['query']['pages'][$key]['revisions'][0] ); - - return $data; - } - - /** - * @group Broken - * Broken because there is currently no revision info in the $pageinfo - * - * @depends testGetRollbackToken - */ - function testWatchRollback( $data ) { - $keys = array_keys( $data[0]['query']['pages'] ); - $key = array_pop( $keys ); - $pageinfo = $data[0]['query']['pages'][$key]; - $revinfo = $pageinfo['revisions'][0]; - - try { - $data = $this->doApiRequest( array( - 'action' => 'rollback', - 'title' => 'UTPage', - 'user' => $revinfo['user'], - 'token' => $pageinfo['rollbacktoken'], - 'watchlist' => 'watch' ) ); - - $this->assertArrayHasKey( 'rollback', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['rollback'] ); - } catch( UsageException $ue ) { - if( $ue->getCodeString() == 'onlyauthor' ) { - $this->markTestIncomplete( "Only one author to 'UTPage', cannot test rollback" ); - } else { - $this->fail( "Received error '" . $ue->getCodeString() . "'" ); - } - } - } - - /** - */ - function testWatchDelete() { - $pageinfo = $this->getTokens(); - - $data = $this->doApiRequest( array( - 'action' => 'delete', - 'token' => $pageinfo['deletetoken'], - 'title' => 'UTPage' ) ); - $this->assertArrayHasKey( 'delete', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['delete'] ); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ) ); - - $this->markTestIncomplete( 'This test needs to verify the deleted article was added to the users watchlist' ); - } -} diff --git a/tests/phpunit/includes/api/PrefixUniquenessTest.php b/tests/phpunit/includes/api/PrefixUniquenessTest.php deleted file mode 100644 index 69b01ea7..00000000 --- a/tests/phpunit/includes/api/PrefixUniquenessTest.php +++ /dev/null @@ -1,24 +0,0 @@ -getModules(); - $prefixes = array(); - - foreach ( $modules as $name => $class ) { - $module = new $class( $main, $name ); - $prefix = $module->getModulePrefix(); - if ( isset( $prefixes[$prefix] ) ) { - $this->fail( "Module prefix '{$prefix}' is shared between {$class} and {$prefixes[$prefix]}" ); - } - $prefixes[$module->getModulePrefix()] = $class; - } - $this->assertTrue( true ); // dummy call to make this test non-incomplete - } -} diff --git a/tests/phpunit/includes/api/RandomImageGenerator.php b/tests/phpunit/includes/api/RandomImageGenerator.php deleted file mode 100644 index 8b6a3849..00000000 --- a/tests/phpunit/includes/api/RandomImageGenerator.php +++ /dev/null @@ -1,463 +0,0 @@ - - */ - -/** - * RandomImageGenerator: does what it says on the tin. - * Can fetch a random image, or also write a number of them to disk with random filenames. - */ -class RandomImageGenerator { - - private $dictionaryFile; - private $minWidth = 400 ; - private $maxWidth = 800 ; - private $minHeight = 400 ; - private $maxHeight = 800 ; - private $shapesToDraw = 5 ; - - /** - * Orientations: 0th row, 0th column, EXIF orientation code, rotation 2x2 matrix that is opposite of orientation - * n.b. we do not handle the 'flipped' orientations, which is why there is no entry for 2, 4, 5, or 7. Those - * seem to be rare in real images anyway - * (we also would need a non-symmetric shape for the images to test those, like a letter F) - */ - private static $orientations = array( - array( - '0thRow' => 'top', - '0thCol' => 'left', - 'exifCode' => 1, - 'counterRotation' => array( array( 1, 0 ), array( 0, 1 ) ) - ), - array( - '0thRow' => 'bottom', - '0thCol' => 'right', - 'exifCode' => 3, - 'counterRotation' => array( array( -1, 0 ), array( 0, -1 ) ) - ), - array( - '0thRow' => 'right', - '0thCol' => 'top', - 'exifCode' => 6, - 'counterRotation' => array( array( 0, 1 ), array( 1, 0 ) ) - ), - array( - '0thRow' => 'left', - '0thCol' => 'bottom', - 'exifCode' => 8, - 'counterRotation' => array( array( 0, -1 ), array( -1, 0 ) ) - ) - ); - - - public function __construct( $options = array() ) { - foreach ( array( 'dictionaryFile', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'shapesToDraw' ) as $property ) { - if ( isset( $options[$property] ) ) { - $this->$property = $options[$property]; - } - } - - // find the dictionary file, to generate random names - if ( !isset( $this->dictionaryFile ) ) { - foreach ( array( - '/usr/share/dict/words', - '/usr/dict/words', - __DIR__ . '/words.txt' ) - as $dictionaryFile ) { - if ( is_file( $dictionaryFile ) and is_readable( $dictionaryFile ) ) { - $this->dictionaryFile = $dictionaryFile; - break; - } - } - } - if ( !isset( $this->dictionaryFile ) ) { - throw new Exception( "RandomImageGenerator: dictionary file not found or not specified properly" ); - } - } - - /** - * Writes random images with random filenames to disk in the directory you specify, or current working directory - * - * @param $number Integer: number of filenames to write - * @param $format String: optional, must be understood by ImageMagick, such as 'jpg' or 'gif' - * @param $dir String: directory, optional (will default to current working directory) - * @return Array: filenames we just wrote - */ - function writeImages( $number, $format = 'jpg', $dir = null ) { - $filenames = $this->getRandomFilenames( $number, $format, $dir ); - $imageWriteMethod = $this->getImageWriteMethod( $format ); - foreach( $filenames as $filename ) { - $this->{$imageWriteMethod}( $this->getImageSpec(), $format, $filename ); - } - return $filenames; - } - - - /** - * Figure out how we write images. This is a factor of both format and the local system - * @param $format (a typical extension like 'svg', 'jpg', etc.) - */ - function getImageWriteMethod( $format ) { - global $wgUseImageMagick, $wgImageMagickConvertCommand; - if ( $format === 'svg' ) { - return 'writeSvg'; - } else { - // figure out how to write images - global $wgExiv2Command; - if ( class_exists( 'Imagick' ) && $wgExiv2Command && is_executable( $wgExiv2Command ) ) { - return 'writeImageWithApi'; - } elseif ( $wgUseImageMagick && $wgImageMagickConvertCommand && is_executable( $wgImageMagickConvertCommand ) ) { - return 'writeImageWithCommandLine'; - } - } - throw new Exception( "RandomImageGenerator: could not find a suitable method to write images in '$format' format" ); - } - - /** - * Return a number of randomly-generated filenames - * Each filename uses two words randomly drawn from the dictionary, like elephantine_spatula.jpg - * - * @param $number Integer: of filenames to generate - * @param $extension String: optional, defaults to 'jpg' - * @param $dir String: optional, defaults to current working directory - * @return Array: of filenames - */ - private function getRandomFilenames( $number, $extension = 'jpg', $dir = null ) { - if ( is_null( $dir ) ) { - $dir = getcwd(); - } - $filenames = array(); - foreach( $this->getRandomWordPairs( $number ) as $pair ) { - $basename = $pair[0] . '_' . $pair[1]; - if ( !is_null( $extension ) ) { - $basename .= '.' . $extension; - } - $basename = preg_replace( '/\s+/', '', $basename ); - $filenames[] = "$dir/$basename"; - } - - return $filenames; - - } - - - /** - * Generate data representing an image of random size (within limits), - * consisting of randomly colored and sized upward pointing triangles against a random background color - * (This data is used in the writeImage* methods). - * @return {Mixed} - */ - public function getImageSpec() { - $spec = array(); - - $spec['width'] = mt_rand( $this->minWidth, $this->maxWidth ); - $spec['height'] = mt_rand( $this->minHeight, $this->maxHeight ); - $spec['fill'] = $this->getRandomColor(); - - $diagonalLength = sqrt( pow( $spec['width'], 2 ) + pow( $spec['height'], 2 ) ); - - $draws = array(); - for ( $i = 0; $i <= $this->shapesToDraw; $i++ ) { - $radius = mt_rand( 0, $diagonalLength / 4 ); - if ( $radius == 0 ) { - continue; - } - $originX = mt_rand( -1 * $radius, $spec['width'] + $radius ); - $originY = mt_rand( -1 * $radius, $spec['height'] + $radius ); - $angle = mt_rand( 0, ( 3.141592/2 ) * $radius ) / $radius; - $legDeltaX = round( $radius * sin( $angle ) ); - $legDeltaY = round( $radius * cos( $angle ) ); - - $draw = array(); - $draw['fill'] = $this->getRandomColor(); - $draw['shape'] = array( - array( 'x' => $originX, 'y' => $originY - $radius ), - array( 'x' => $originX + $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX - $legDeltaX, 'y' => $originY + $legDeltaY ), - array( 'x' => $originX, 'y' => $originY - $radius ) - ); - $draws[] = $draw; - - } - - $spec['draws'] = $draws; - - return $spec; - } - - /** - * Given array( array('x' => 10, 'y' => 20), array( 'x' => 30, y=> 5 ) ) - * returns "10,20 30,5" - * Useful for SVG and imagemagick command line arguments - * @param $shape: Array of arrays, each array containing x & y keys mapped to numeric values - * @return string - */ - static function shapePointsToString( $shape ) { - $points = array(); - foreach ( $shape as $point ) { - $points[] = $point['x'] . ',' . $point['y']; - } - return join( " ", $points ); - } - - /** - * Based on image specification, write a very simple SVG file to disk. - * Ignores the background spec because transparency is cool. :) - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (which is obviously always svg here) - * @param $filename: filename to write to - */ - public function writeSvg( $spec, $format, $filename ) { - $svg = new SimpleXmlElement( '' ); - $svg->addAttribute( 'xmlns', 'http://www.w3.org/2000/svg' ); - $svg->addAttribute( 'version', '1.1' ); - $svg->addAttribute( 'width', $spec['width'] ); - $svg->addAttribute( 'height', $spec['height'] ); - $g = $svg->addChild( 'g' ); - foreach ( $spec['draws'] as $drawSpec ) { - $shape = $g->addChild( 'polygon' ); - $shape->addAttribute( 'fill', $drawSpec['fill'] ); - $shape->addAttribute( 'points', self::shapePointsToString( $drawSpec['shape'] ) ); - }; - if ( ! $fh = fopen( $filename, 'w' ) ) { - throw new Exception( "couldn't open $filename for writing" ); - } - fwrite( $fh, $svg->asXML() ); - if ( !fclose($fh) ) { - throw new Exception( "couldn't close $filename" ); - } - } - - /** - * Based on an image specification, write such an image to disk, using Imagick PHP extension - * @param $spec: spec describing background and circles to draw - * @param $format: file format to write - * @param $filename: filename to write to - */ - public function writeImageWithApi( $spec, $format, $filename ) { - // this is a hack because I can't get setImageOrientation() to work. See below. - global $wgExiv2Command; - - $image = new Imagick(); - /** - * If the format is 'jpg', will also add a random orientation -- the image will be drawn rotated with triangle points - * facing in some direction (0, 90, 180 or 270 degrees) and a countering rotation should turn the triangle points upward again - */ - $orientation = self::$orientations[0]; // default is normal orientation - if ( $format == 'jpg' ) { - $orientation = self::$orientations[ array_rand( self::$orientations ) ]; - $spec = self::rotateImageSpec( $spec, $orientation['counterRotation'] ); - } - - $image->newImage( $spec['width'], $spec['height'], new ImagickPixel( $spec['fill'] ) ); - - foreach ( $spec['draws'] as $drawSpec ) { - $draw = new ImagickDraw(); - $draw->setFillColor( $drawSpec['fill'] ); - $draw->polygon( $drawSpec['shape'] ); - $image->drawImage( $draw ); - } - - $image->setImageFormat( $format ); - - // this doesn't work, even though it's documented to do so... - // $image->setImageOrientation( $orientation['exifCode'] ); - - $image->writeImage( $filename ); - - // because the above setImageOrientation call doesn't work... nor can I get an external imagemagick binary to do this either... - // hacking this for now (only works if you have exiv2 installed, a program to read and manipulate exif) - if ( $wgExiv2Command ) { - $cmd = wfEscapeShellArg( $wgExiv2Command ) - . " -M " - . wfEscapeShellArg( "set Exif.Image.Orientation " . $orientation['exifCode'] ) - . " " - . wfEscapeShellArg( $filename ); - - $retval = 0; - $err = wfShellExec( $cmd, $retval ); - if ( $retval !== 0 ) { - print "Error with $cmd: $retval, $err\n"; - } - } - } - - /** - * Given an image specification, produce rotated version - * This is used when simulating a rotated image capture with EXIF orientation - * @param $spec Object returned by getImageSpec - * @param $matrix 2x2 transformation matrix - * @return transformed Spec - */ - private static function rotateImageSpec( &$spec, $matrix ) { - $tSpec = array(); - $dims = self::matrixMultiply2x2( $matrix, $spec['width'], $spec['height'] ); - $correctionX = 0; - $correctionY = 0; - if ( $dims['x'] < 0 ) { - $correctionX = abs( $dims['x'] ); - } - if ( $dims['y'] < 0 ) { - $correctionY = abs( $dims['y'] ); - } - $tSpec['width'] = abs( $dims['x'] ); - $tSpec['height'] = abs( $dims['y'] ); - $tSpec['fill'] = $spec['fill']; - $tSpec['draws'] = array(); - foreach( $spec['draws'] as $draw ) { - $tDraw = array( - 'fill' => $draw['fill'], - 'shape' => array() - ); - foreach( $draw['shape'] as $point ) { - $tPoint = self::matrixMultiply2x2( $matrix, $point['x'], $point['y'] ); - $tPoint['x'] += $correctionX; - $tPoint['y'] += $correctionY; - $tDraw['shape'][] = $tPoint; - } - $tSpec['draws'][] = $tDraw; - } - return $tSpec; - } - - /** - * Given a matrix and a pair of images, return new position - * @param $matrix: 2x2 rotation matrix - * @param $x: x-coordinate number - * @param $y: y-coordinate number - * @return Array transformed with properties x, y - */ - private static function matrixMultiply2x2( $matrix, $x, $y ) { - return array( - 'x' => $x * $matrix[0][0] + $y * $matrix[0][1], - 'y' => $x * $matrix[1][0] + $y * $matrix[1][1] - ); - } - - - /** - * Based on an image specification, write such an image to disk, using the command line ImageMagick program ('convert'). - * - * Sample command line: - * $ convert -size 100x60 xc:rgb(90,87,45) \ - * -draw 'fill rgb(12,34,56) polygon 41,39 44,57 50,57 41,39' \ - * -draw 'fill rgb(99,123,231) circle 59,39 56,57' \ - * -draw 'fill rgb(240,12,32) circle 50,21 50,3' filename.png - * - * @param $spec: spec describing background and shapes to draw - * @param $format: file format to write (unused by this method but kept so it has the same signature as writeImageWithApi) - * @param $filename: filename to write to - */ - public function writeImageWithCommandLine( $spec, $format, $filename ) { - global $wgImageMagickConvertCommand; - $args = array(); - $args[] = "-size " . wfEscapeShellArg( $spec['width'] . 'x' . $spec['height'] ); - $args[] = wfEscapeShellArg( "xc:" . $spec['fill'] ); - foreach( $spec['draws'] as $draw ) { - $fill = $draw['fill']; - $polygon = self::shapePointsToString( $draw['shape'] ); - $drawCommand = "fill $fill polygon $polygon"; - $args[] = '-draw ' . wfEscapeShellArg( $drawCommand ); - } - $args[] = wfEscapeShellArg( $filename ); - - $command = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " . implode( " ", $args ); - $retval = null; - wfShellExec( $command, $retval ); - return ( $retval === 0 ); - } - - /** - * Generate a string of random colors for ImageMagick or SVG, like "rgb(12, 37, 98)" - * - * @return {String} - */ - public function getRandomColor() { - $components = array(); - for ($i = 0; $i <= 2; $i++ ) { - $components[] = mt_rand( 0, 255 ); - } - return 'rgb(' . join(', ', $components) . ')'; - } - - /** - * Get an array of random pairs of random words, like array( array( 'foo', 'bar' ), array( 'quux', 'baz' ) ); - * - * @param $number Integer: number of pairs - * @return Array: of two-element arrays - */ - private function getRandomWordPairs( $number ) { - $lines = $this->getRandomLines( $number * 2 ); - // construct pairs of words - $pairs = array(); - $count = count( $lines ); - for( $i = 0; $i < $count; $i += 2 ) { - $pairs[] = array( $lines[$i], $lines[$i+1] ); - } - return $pairs; - } - - - /** - * Return N random lines from a file - * - * Will throw exception if the file could not be read or if it had fewer lines than requested. - * - * @param $number_desired Integer: number of lines desired - * @return Array: of exactly n elements, drawn randomly from lines the file - */ - private function getRandomLines( $number_desired ) { - $filepath = $this->dictionaryFile; - - // initialize array of lines - $lines = array(); - for ( $i = 0; $i < $number_desired; $i++ ) { - $lines[] = null; - } - - /* - * This algorithm obtains N random lines from a file in one single pass. It does this by replacing elements of - * a fixed-size array of lines, less and less frequently as it reads the file. - */ - $fh = fopen( $filepath, "r" ); - if ( !$fh ) { - throw new Exception( "couldn't open $filepath" ); - } - $line_number = 0; - $max_index = $number_desired - 1; - while( !feof( $fh ) ) { - $line = fgets( $fh ); - if ( $line !== false ) { - $line_number++; - $line = trim( $line ); - if ( mt_rand( 0, $line_number ) <= $max_index ) { - $lines[ mt_rand( 0, $max_index ) ] = $line; - } - } - } - fclose( $fh ); - if ( $line_number < $number_desired ) { - throw new Exception( "not enough lines in $filepath" ); - } - - return $lines; - } - -} diff --git a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php b/tests/phpunit/includes/api/format/ApiFormatPhpTest.php deleted file mode 100644 index 8209f591..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatPhpTest.php +++ /dev/null @@ -1,19 +0,0 @@ -apiRequest( 'php', array( 'action' => 'query', 'meta' => 'siteinfo' ) ); - - $this->assertInternalType( 'array', unserialize( $data ) ); - $this->assertGreaterThan( 0, count( (array) $data ) ); - - - } - -} diff --git a/tests/phpunit/includes/api/format/ApiFormatTestBase.php b/tests/phpunit/includes/api/format/ApiFormatTestBase.php deleted file mode 100644 index a0b7b020..00000000 --- a/tests/phpunit/includes/api/format/ApiFormatTestBase.php +++ /dev/null @@ -1,22 +0,0 @@ -createPrinterByName( $format ); - $printer->setUnescapeAmps( false ); - - $printer->initPrinter( false ); - - ob_start(); - $printer->execute(); - $out = ob_get_clean(); - - $printer->closePrinter(); - - return $out; - } -} diff --git a/tests/phpunit/includes/api/generateRandomImages.php b/tests/phpunit/includes/api/generateRandomImages.php deleted file mode 100644 index ee345623..00000000 --- a/tests/phpunit/includes/api/generateRandomImages.php +++ /dev/null @@ -1,51 +0,0 @@ -writeImages( $number, $format ); - } -} - -$maintClass = 'GenerateRandomImages'; -require( RUN_MAINTENANCE_IF_MAIN ); - - diff --git a/tests/phpunit/includes/api/words.txt b/tests/phpunit/includes/api/words.txt deleted file mode 100644 index 7ce23ee3..00000000 --- a/tests/phpunit/includes/api/words.txt +++ /dev/null @@ -1,1000 +0,0 @@ -Andaquian -Anoplanthus -Araquaju -Astrophyton -Avarish -Batonga -Bdellidae -Betoyan -Bismarck -Britishness -Carmen -Chatillon -Clement -Coryphaena -Croton -Cyrillianism -Dagomba -Decimus -Dichorisandra -Duculinae -Empusa -Escallonia -Fathometer -Fon -Fundulinae -Gadswoons -Gederathite -Gemini -Gerbera -Gregarinida -Gyracanthus -Halopsychidae -Hasidim -Hemerobius -Ichthyosauridae -Iscariot -Jeames -Jesuitry -Jovian -Judaization -Katie -Ladin -Langhian -Lapithaean -Lisette -Macrochira -Malaxis -Malvastrum -Maranhao -Marxian -Maurist -Metrosideros -Micky -Microsporon -Odacidae -Ophiuchid -Osmorhiza -Paguma -Palesman -Papayaceae -Pastinaca -Philoxenian -Pleurostigma -Rarotongan -Rhodoraceae -Rong -Saho -Sanyakoan -Sardanapalian -Sauropoda -Sedentaria -Shambu -Shukulumbwe -Solonian -Spaniardization -Spirochaetaceae -Stomatopoda -Stratiotes -Taiwanhemp -Titanically -Venetianed -Victrola -Yuman -abatis -abaton -abjoint -acanthoma -acari -acceptance -actinography -acuteness -addiment -adelite -adelomorphic -adelphogamy -adipocele -aelurophobia -affined -aflaunt -agathokakological -aischrolatreia -alarmedly -alebench -aleurone -allelotropic -allerion -alloplastic -allowable -alternacy -alternariose -altricial -ambitionist -amendment -amiableness -amicableness -ammo -amortizable -anchorate -anemometrically -angelocracy -angelological -anodal -anomalure -antedate -antiagglutinin -antirationalist -antiscorbutic -antisplasher -antithesize -antiunionist -antoecian -apolegamic -appropriation -archididascalian -archival -arteriophlebotomy -articulable -asseveration -assignation -atelo -atrienses -atrophy -atterminement -atypic -automower -aveloz -awrist -azteca -bairnteam -balsamweed -bannerman -beardy -becry -beek -beggarwise -bescab -bestness -bethel -bewildering -bibliophilism -bitterblain -blakeberyed -boccarella -bocedization -boobyalla -bourbon -bowbent -bowerbird -brachygnathous -brail -branchiferous -brelaw -brew -brideweed -bridgeable -brombenzamide -buddler -burbankian -burr -buskin -cacochymical -calefactory -caliper -canaliculus -candidature -canellaceous -canniness -canning -cantilene -carbonatation -carthamic -caseum -caudated -causationist -ceruleite -chalder -chalta -charmel -chekan -chillness -chirogymnast -chirpling -chlorinous -cholanthrene -chondroblast -chromatography -chromophilous -chronical -cicatrice -cinchonine -city -clubbing -coastal -coaxially -coercible -coeternity -coff -coinventor -collyba -combinator -complanation -comprehensibility -conchuela -congenital -context -contranatural -corallum -cordately -cornupete -corolliferous -coroneted -corticosterone -coseat -cottage -crocetin -crossleted -crottels -curvedness -cycadeous -cyclism -cylindrically -cynanche -cyrtoceratitic -cystospasm -danceress -dancette -dawny -daydreamy -debar -decarburization -decorousness -decrepitness -delirious -deozonizer -dermatosis -desma -deutencephalic -diacetate -diarthrodial -diathermy -dicolic -dimastigate -dimidiation -dipetto -disavowable -disintrench -disman -dismay -disorder -disoxygenation -dithionous -dogman -dragonfly -dramatical -drawspan -drubbly -drunk -duskly -ecderonic -ectocuniform -ectocyst -ehrwaldite -electrocute -elemicin -embracing -emotionality -enactment -enamor -enclave -endameba -endochylous -endocrinologist -endolymph -endothecal -entasia -epigeous -episcopicide -epitrichial -erminee -erraticalness -eruptivity -erythrocytoschisis -esperance -estuous -eucrystalline -eugeny -evacuant -everbloomer -evocation -exarchateship -exasperate -excorticate -excrementary -exile -expandedly -exponency -expressionist -expulsion -extemporary -extollation -extortive -extrabulbar -extraprostatic -facticide -fairer -fakery -fasibitikite -fatiscent -fearless -febrifuge -ferie -fibrousness -fingered -fisheye -flagpole -flagrantness -fleche -fluidism -folliculin -footbreadth -forceps -forecontrive -forthbring -foveated -fuchsin -fungicidal -funori -gamelang -gametically -garvanzo -gasoliner -gastrophile -germproof -gerontism -gigantical -glaciology -godmotherhood -gooseherd -gordunite -gove -gracilis -greathead -grieveship -guidable -gyromancy -gyrostat -habitus -hailweed -handhole -hangalai -haznadar -heliced -hemihypertrophy -hemimorphic -hemistrumectomy -heptavalent -heptite -herbalist -herpetology -hesperid -hexacarbon -hieromnemon -hobbyless -holodactylic -homoeoarchy -hopperings -hospitable -houseboat -huh -huntedly -hydroponics -hydrosomal -hyperdactylia -hyperperistalsis -hypogeocarpous -ideogram -idiopathical -illegitimate -imambarah -impotently -improvise -impuberal -inaccurately -incarnant -inchoation -incliner -incredulous -indiscriminateness -indulgenced -inebriation -inexpressiveness -infibulate -inflectedness -iniome -ink -inquietly -insaturable -insinuative -instiller -institutive -insultproof -interactionist -intercensal -interpenetrable -intertranspicuous -intrinsicality -inwards -iridiocyte -iridoparalysis -irreportable -isoprene -isosmotic -izard -jacuaru -jaculative -jerkined -joe -joyous -julienne -justicehood -kali -kalidium -katha -kathal -keelage -keratomycosis -khaki -khedival -kinkily -knife -kolo -kraken -kwarta -labba -labber -laboress -lacunar -latch -lauric -lawter -lectotype -leeches -legible -lepidosteoid -leucobasalt -leverer -libellate -limnimeter -lithography -lithotypic -locomotor -logarithmetically -logistician -lyncine -lysogenesis -machan -macromyelon -maharana -mandibulate -manganapatite -marchpane -mas -masochistic -mastaba -matching -meditatively -megalopolitan -melaniline -mentum -mercaptides -mestome -metasomatism -meterless -micronuclear -micropetalous -microreaction -microsporophore -mileway -milliarium -millisecond -misbind -miscollocation -misreader -modernicide -modification -modulant -monkfish -monoamino -monocarbide -monographical -morphinomaniac -mullein -munge -mutilate -mycophagist -myelosarcoma -myospasm -myriadly -nagaika -naphthionate -natant -naviculaeform -nayward -neallotype -necrophilia -nectared -neigher -neogamous -neurodynia -neurorthopteran -nidation -nieceship -nitrobacteria -nitrosification -nogheaded -nonassertive -noneuphonious -nonextant -nonincrease -nonintermittent -nonmetallic -nonprehensile -nonremunerative -nonsocial -nonvesting -noontime -noreaster -nounal -nub -nucleoplasm -nullisome -numero -numerous -oblongatal -observe -obtusilingual -obvert -occipitoatlantal -oceanside -ochlophobist -odontiasis -opalescence -opticon -oraculousness -orarium -organically -orthopedically -ostosis -overadvance -overbuilt -overdiscouragement -overdoer -overhardy -overjocular -overmagnify -overofficered -overpotent -overprizer -overrunner -overshrink -oversimply -oversplash -ovology -oxskin -oxychloride -oxygenant -ozokerite -pactional -palaeoanthropography -palaeographical -palaeopsychology -palliasse -palpebral -pandaric -pantelegraph -papicolist -papulate -parakinetic -parasitism -parochialic -parochialize -passionlike -patch -paucidentate -pawnbrokeress -pecite -pecky -pedipulation -pellitory -perfilograph -periblast -perigemmal -periost -periplus -perishable -periwig -permansive -persistingly -persymmetrical -phantom -phasmatrope -philocaly -philogyny -philosophister -philotherianism -phorology -phototrophic -phrator -phratral -phthisipneumony -physogastry -phytologic -phytoptid -pianograph -picqueter -piculet -pigeoner -pimaric -pinesap -pist -planometer -platano -playful -plea -pleuropneumonic -plowwoman -plump -pluviographical -pneumocele -podophthalmate -polyad -polythalamian -poppyhead -portamento -portmanteau -portraitlike -possible -potassamide -powderer -praepubis -preanesthetic -prebarbaric -predealer -predomination -prefactory -preirrigational -prelector -presbytership -presecure -preservable -prespecialist -preventionism -prewound -princely -priorship -proannexationist -proanthropos -probeable -probouleutic -profitless -proplasma -prosectorial -protecting -protochemistry -protosulphate -pseudoataxia -psilology -psychoneurotic -pterygial -publicist -purgation -purplishness -putatively -pyracene -pyrenomycete -pyromancy -pyrophone -quadroon -quailhead -qualifier -quaternal -rabblelike -rambunctious -rapidness -ratably -rationalism -razor -reannoy -recultivation -regulable -reimplant -reimposition -reimprison -reinjure -reinspiration -reintroduce -remantle -reprehensibility -reptant -require -resteal -restful -returnability -revisableness -rewash -rewhirl -reyield -rhizotomy -rhodamine -rigwiddie -rimester -ripper -rippet -rockish -rockwards -rollicky -roosters -rooted -rosal -rozum -saccharated -sagamore -sagy -salesmanship -salivous -sallet -salta -saprostomous -satiation -sauropsid -sawarra -sawback -scabish -scabrate -scampavia -scientificophilosophical -scirrosity -scoliometer -scolopendrelloid -secantly -seignioral -semibull -semic -seminarianism -semiped -semiprivate -semispherical -semispontaneous -seneschal -septendecimal -serotherapist -servation -sesquisulphuret -severish -sextipartite -sextubercular -shipyard -shuckpen -siderosis -silex -sillyhow -silverbelly -silverbelly -simulacrum -sisham -sixte -skeiner -skiapod -slopped -slubby -smalts -sockmaker -solute -somethingness -somnify -southwester -spathilla -spectrochemical -sphagnology -spinales -spiriting -spirling -spirochetemia -spreadboard -spurflower -squawdom -squeezing -staircase -staker -stamphead -statolith -stekan -stellulate -stinker -stomodaea -streamingly -strikingness -strouthocamelian -stuprum -subacutely -subboreal -subcontractor -subendorsement -subprofitable -subserviate -subsneer -subungual -sucuruju -sugan -sulphocarbolate -summerwood -superficialist -superinference -superregenerative -supplicate -suspendible -synchronizer -syntectic -tachyglossate -tailless -taintment -takingly -taletelling -tarpon -tasteful -taxeater -taxy -teache -teachless -teg -tegmen -teletyper -temperable -ten -tenent -teskere -testes -thallogen -thapsia -thewness -thickety -thiobacteria -thorniness -throwing -thyroprivic -tinnitus -tocalote -tolerationist -tonalamatl -torvous -totality -tottering -toug -tracheopathia -tragedical -translucent -trifoveolate -trilaurin -trophoplasmatic -trunkless -turbanless -turnpiker -twangle -twitterboned -ultraornate -umbilication -unabatingly -unabjured -unadequateness -unaffectedness -unarriving -unassorted -unattacked -unbenumbed -unboasted -unburning -uncensorious -uncongested -uncontemnedly -uncontemporary -uncrook -uncrystallizability -uncurb -uncustomariness -underbillow -undercanopy -underestimation -underhanging -underpetticoated -underpropped -undersole -understocking -underworld -undevout -undisappointing -undistinctive -unfiscal -unfluted -unfreckled -ungentilize -unglobe -unhelped -unhomogeneously -unifoliate -uninflammable -uninterrogated -unisonal -unkindled -unlikeableness -unlisty -unlocked -unmoving -unmultipliable -unnestled -unnoticed -unobservable -unobviated -unoffensively -unofficerlike -unpoetic -unpractically -unquestionableness -unrehearsed -unrevised -unrhetorical -unsadden -unsaluting -unscriptural -unseeking -unshowed -unsolicitous -unsprouted -unsubjective -unsubsidized -unsymbolic -untenant -unterrified -untranquil -untraversed -untrusty -untying -unwillful -unwinding -upspring -uptwist -urachovesical -uropygial -vagabondism -varicoid -varletess -vasal -ventrocaudal -verisimilitude -vermigerous -vibrometer -viminal -virus -vocationalism -voguey -vulnerability -waggle -wamblingly -warmus -waxer -waying -wedgeable -wellmaker -whomever -wigged -witchlike -wokas -woodrowel -woodsman -woolding -xanthelasmic -xiphosternum -yachtman -yachtsmanlike -yelp -zoophytal \ No newline at end of file diff --git a/tests/phpunit/includes/cache/GenderCacheTest.php b/tests/phpunit/includes/cache/GenderCacheTest.php deleted file mode 100644 index a8b987e2..00000000 --- a/tests/phpunit/includes/cache/GenderCacheTest.php +++ /dev/null @@ -1,101 +0,0 @@ -getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTMalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'male' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTFemale' ); - if( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTFemalePassword' ); - } - //ensure the right gender - $user->setOption( 'gender', 'female' ); - $user->saveSettings(); - - $user = User::newFromName( 'UTDefaultGender' ); - if( $user->getID() == 0 ) { - $user->addToDatabase(); - $user->setPassword( 'UTDefaultGenderPassword' ); - } - //ensure the default gender - $user->setOption( 'gender', null ); - $user->saveSettings(); - } - - /** - * test usernames - * - * @dataProvider dataUserName - */ - function testUserName( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $username ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - /** - * genderCache should work with user objects, too - * - * @dataProvider dataUserName - */ - function testUserObjects( $username, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $user = User::newFromName( $username ); - $gender = $genderCache->getGenderOf( $user ); - $this->assertEquals( $gender, $expectedGender, "GenderCache normal" ); - } - - function dataUserName() { - return array( - array( 'UTMale', 'male' ), - array( 'UTFemale', 'female' ), - array( 'UTDefaultGender', 'unknown' ), - array( 'UTNotExist', 'unknown' ), - //some not valid user - array( '127.0.0.1', 'unknown' ), - array( 'user@test', 'unknown' ), - ); - } - - /** - * test strip of subpages to avoid unnecessary queries - * against the never existing username - * - * @dataProvider dataStripSubpages - */ - function testStripSubpages( $pageWithSubpage, $expectedGender ) { - $genderCache = GenderCache::singleton(); - $gender = $genderCache->getGenderOf( $pageWithSubpage ); - $this->assertEquals( $gender, $expectedGender, "GenderCache must strip of subpages" ); - } - - function dataStripSubpages() { - return array( - array( 'UTMale/subpage', 'male' ), - array( 'UTFemale/subpage', 'female' ), - array( 'UTDefaultGender/subpage', 'unknown' ), - array( 'UTNotExist/subpage', 'unknown' ), - array( '127.0.0.1/subpage', 'unknown' ), - ); - } -} diff --git a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php b/tests/phpunit/includes/cache/ProcessCacheLRUTest.php deleted file mode 100644 index 30bfb124..00000000 --- a/tests/phpunit/includes/cache/ProcessCacheLRUTest.php +++ /dev/null @@ -1,239 +0,0 @@ -assertAttributeEquals( array(), 'cache', $cache, $msg ); - } - - /** - * Helper to fill a cache object passed by reference - */ - function fillCache( &$cache, $numEntries ) { - // Fill cache with three values - for( $i=1; $i<=$numEntries; $i++) { - $cache->set( "cache-key-$i", "prop-$i", "value-$i" ); - } - } - - /** - * Generates an array of what would be expected in cache for a given cache - * size and a number of entries filled in sequentially - */ - function getExpectedCache( $cacheMaxEntries, $entryToFill ) { - $expected = array(); - - if( $entryToFill === 0 ) { - # The cache is empty! - return array(); - } elseif( $entryToFill <= $cacheMaxEntries ) { - # Cache is not fully filled - $firstKey = 1; - } else { - # Cache overflowed - $firstKey = 1 + $entryToFill - $cacheMaxEntries; - } - - $lastKey = $entryToFill; - - for( $i=$firstKey; $i<=$lastKey; $i++ ) { - $expected["cache-key-$i"] = array( "prop-$i" => "value-$i" ); - } - return $expected; - } - - /** - * Highlight diff between assertEquals and assertNotSame - */ - function testPhpUnitArrayEquality() { - $one = array( 'A' => 1, 'B' => 2 ); - $two = array( 'B' => 2, 'A' => 1 ); - $this->assertEquals( $one, $two ); // == - $this->assertNotSame( $one, $two ); // === - } - - /** - * @dataProvider provideInvalidConstructorArg - * @expectedException MWException - */ - function testConstructorGivenInvalidValue( $maxSize ) { - $c = new ProcessCacheLRUTestable( $maxSize ); - } - - /** - * Value which are forbidden by the constructor - */ - function provideInvalidConstructorArg() { - return array( - array( null ), - array( array() ), - array( new stdClass() ), - array( 0 ), - array( '5' ), - array( -1 ), - ); - } - - function testAddAndGetAKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - // First set just one value - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $this->assertEquals( 1, $oneCache->getEntriesCount() ); - $this->assertTrue( $oneCache->has( 'cache-key', 'prop1' ) ); - $this->assertEquals( 'value1', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - function testDeleteOldKey() { - $oneCache = new ProcessCacheLRUTestable( 1 ); - $this->assertCacheEmpty( $oneCache ); - - $oneCache->set( 'cache-key', 'prop1', 'value1' ); - $oneCache->set( 'cache-key', 'prop1', 'value2' ); - $this->assertEquals( 'value2', $oneCache->get( 'cache-key', 'prop1' ) ); - } - - /** - * This test that we properly overflow when filling a cache with - * a sequence of always different cache-keys. Meant to verify we correclty - * delete the older key. - * - * @dataProvider provideCacheFilling - * @param $cacheMaxEntries Maximum entry the created cache will hold - * @param $entryToFill Number of entries to insert in the created cache. - */ - function testFillingCache( $cacheMaxEntries, $entryToFill, $msg = '' ) { - $cache = new ProcessCacheLRUTestable( $cacheMaxEntries ); - $this->fillCache( $cache, $entryToFill); - - $this->assertSame( - $this->getExpectedCache( $cacheMaxEntries, $entryToFill ), - $cache->getCache(), - "Filling a $cacheMaxEntries entries cache with $entryToFill entries" - ); - - } - - /** - * Provider for testFillingCache - */ - function provideCacheFilling() { - // ($cacheMaxEntries, $entryToFill, $msg='') - return array( - array( 1, 0 ), - array( 1, 1 ), - array( 1, 2 ), # overflow - array( 5, 33 ), # overflow - ); - - } - - /** - * Create a cache with only one remaining entry then update - * the first inserted entry. Should bump it to the top. - */ - function testReplaceExistingKeyShouldBumpEntryToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - // Fill cache leaving just one remaining slot - $this->fillCache( $cache, $maxEntries - 1 ); - - // Set an existing cache key - $cache->set( "cache-key-1", "prop-1", "new-value-for-1" ); - - $this->assertSame( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-1' => array( 'prop-1' => 'new-value-for-1' ), - ), - $cache->getCache() - ); - } - - function testRecentlyAccessedKeyStickIn() { - $cache = new ProcessCacheLRUTestable( 2 ); - $cache->set( 'first' , 'prop1', 'value1' ); - $cache->set( 'second', 'prop2', 'value2' ); - - // Get first - $cache->get( 'first', 'prop1' ); - // Cache a third value, should invalidate the least used one - $cache->set( 'third', 'prop3', 'value3' ); - - $this->assertFalse( $cache->has( 'second', 'prop2' ) ); - } - - /** - * This first create a full cache then update the value for the 2nd - * filled entry. - * Given a cache having 1,2,3 as key, updating 2 should bump 2 to - * the top of the queue with the new value: 1,3,2* (* = updated). - */ - function testReplaceExistingKeyInAFullCacheShouldBumpToTop() { - $maxEntries = 3; - - $cache = new ProcessCacheLRUTestable( $maxEntries ); - $this->fillCache( $cache, $maxEntries ); - - // Set an existing cache key - $cache->set( "cache-key-2", "prop-2", "new-value-for-2" ); - $this->assertSame( - array( - 'cache-key-1' => array( 'prop-1' => 'value-1' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-2' => array( 'prop-2' => 'new-value-for-2' ), - ), - $cache->getCache() - ); - $this->assertEquals( 'new-value-for-2', - $cache->get( 'cache-key-2', 'prop-2' ) - ); - } - - function testBumpExistingKeyToTop() { - $cache = new ProcessCacheLRUTestable( 3 ); - $this->fillCache( $cache, 3 ); - - // Set the very first cache key to a new value - $cache->set( "cache-key-1", "prop-1", "new value for 1" ); - $this->assertEquals( - array( - 'cache-key-2' => array( 'prop-2' => 'value-2' ), - 'cache-key-3' => array( 'prop-3' => 'value-3' ), - 'cache-key-1' => array( 'prop-1' => 'new value for 1' ), - ), - $cache->getCache() - ); - - } - -} - -/** - * Overrides some ProcessCacheLRU methods and properties accessibility. - */ -class ProcessCacheLRUTestable extends ProcessCacheLRU { - public $cache = array(); - - public function getCache() { - return $this->cache; - } - public function getEntriesCount() { - return count( $this->cache ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php deleted file mode 100644 index e37cd445..00000000 --- a/tests/phpunit/includes/db/DatabaseSQLTest.php +++ /dev/null @@ -1,147 +0,0 @@ -db->getType() !== 'mysql' ) { - $this->markTestSkipped( 'No mysql database' ); - } - } - - /** - * @dataProvider dataSelectSQLText - */ - function testSelectSQLText( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->selectSQLText( - isset( $sql['tables'] ) ? $sql['tables'] : array(), - isset( $sql['fields'] ) ? $sql['fields'] : array(), - isset( $sql['conds'] ) ? $sql['conds'] : array(), - __METHOD__, - isset( $sql['options'] ) ? $sql['options'] : array(), - isset( $sql['join_conds'] ) ? $sql['join_conds'] : array() - ) ), $sqlText ); - } - - function dataSelectSQLText() { - return array( - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . - "WHERE alias = 'text'" - ), - array( - array( - 'tables' => 'table', - 'fields' => array( 'field', 'alias' => 'field2' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - ), - "SELECT field,field2 AS alias " . - "FROM `unittest_table` " . - "WHERE alias = 'text' " . - "ORDER BY field " . - "LIMIT 1" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - )), - ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . - "ORDER BY field " . - "LIMIT 1" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => 'field', 'HAVING' => 'COUNT(*) > 1' ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - )), - ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . - "GROUP BY field HAVING COUNT(*) > 1 " . - "LIMIT 1" - ), - array( - array( - 'tables' => array( 'table', 't2' => 'table2' ), - 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), - 'conds' => array( 'alias' => 'text' ), - 'options' => array( 'LIMIT' => 1, 'GROUP BY' => array( 'field', 'field2' ), 'HAVING' => array( 'COUNT(*) > 1', 'field' => 1 ) ), - 'join_conds' => array( 't2' => array( - 'LEFT JOIN', 'tid = t2.id' - )), - ), - "SELECT tid,field,field2 AS alias,t2.id " . - "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . - "WHERE alias = 'text' " . - "GROUP BY field,field2 HAVING (COUNT(*) > 1) AND field = '1' " . - "LIMIT 1" - ), - ); - } - - /** - * @dataProvider dataConditional - */ - function testConditional( $sql, $sqlText ) { - $this->assertEquals( trim( $this->db->conditional( - $sql['conds'], - $sql['true'], - $sql['false'] - ) ), $sqlText ); - } - - function dataConditional() { - return array( - array( - array( - 'conds' => array( 'field' => 'text' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => array( 'field' => 'text', 'field2' => 'anothertext' ), - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field = 'text' AND field2 = 'anothertext' THEN 1 ELSE NULL END)" - ), - array( - array( - 'conds' => 'field=1', - 'true' => 1, - 'false' => 'NULL', - ), - "(CASE WHEN field=1 THEN 1 ELSE NULL END)" - ), - ); - } -} \ No newline at end of file diff --git a/tests/phpunit/includes/db/DatabaseSqliteTest.php b/tests/phpunit/includes/db/DatabaseSqliteTest.php deleted file mode 100644 index d226598b..00000000 --- a/tests/phpunit/includes/db/DatabaseSqliteTest.php +++ /dev/null @@ -1,326 +0,0 @@ -lastQuery = $sql; - return true; - } - - function replaceVars( $s ) { - return parent::replaceVars( $s ); - } -} - -/** - * @group sqlite - * @group Database - */ -class DatabaseSqliteTest extends MediaWikiTestCase { - var $db; - - public function setUp() { - if ( !Sqlite::isPresent() ) { - $this->markTestSkipped( 'No SQLite support detected' ); - } - $this->db = new MockDatabaseSqlite(); - if ( version_compare( $this->db->getServerVersion(), '3.6.0', '<' ) ) { - $this->markTestSkipped( "SQLite at least 3.6 required, {$this->db->getServerVersion()} found" ); - } - } - - private function replaceVars( $sql ) { - // normalize spacing to hide implementation details - return preg_replace( '/\s+/', ' ', $this->db->replaceVars( $sql ) ); - } - - private function assertResultIs( $expected, $res ) { - $this->assertNotNull( $res ); - $i = 0; - foreach( $res as $row ) { - foreach( $expected[$i] as $key => $value ) { - $this->assertTrue( isset( $row->$key ) ); - $this->assertEquals( $value, $row->$key ); - } - $i++; - } - $this->assertEquals( count( $expected ), $i, 'Unexpected number of rows' ); - } - - public function testReplaceVars() { - $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); - - $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );", - $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo1 REAL, foo2 REAL, foo3 REAL );", - $this->replaceVars( "CREATE TABLE foo ( foo1 FLOAT, foo2 DOUBLE( 1,10), foo3 DOUBLE PRECISION );" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );", - $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" ) - ); - - $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );", - $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ), - 'Table name changed' - ); - - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY NOT NULL AUTO_INCREMENT );" ) - ); - $this->assertEquals( "CREATE TABLE foo ( foobar INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL );", - $this->replaceVars("CREATE TABLE foo ( foobar INT PRIMARY KEY AUTO_INCREMENT NOT NULL );" ) - ); - - $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)", - $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" ) - ); - - $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42", - $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" ) - ); - } - - public function testTableName() { - // @todo Moar! - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertEquals( 'foo', $db->tableName( 'foo' ) ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $db->tablePrefix( 'foo' ); - $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) ); - $this->assertEquals( 'foobar', $db->tableName( 'bar' ) ); - } - - public function testDuplicateTableStructure() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE foo(foo, barfoo)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE TABLE "bar"(foo, barfoo)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Normal table duplication' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE TABLE "baz"(foo, barfoo)', - $db->selectField( 'sqlite_temp_master', 'sql', array( 'name' => 'baz' ) ), - 'Creation of temporary duplicate' - ); - $this->assertEquals( 0, - $db->selectField( 'sqlite_master', 'COUNT(*)', array( 'name' => 'baz' ) ), - 'Create a temporary duplicate only' - ); - } - - public function testDuplicateTableStructureVirtual() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - if ( $db->getFulltextSearchModule() != 'FTS3' ) { - $this->markTestSkipped( 'FTS3 not supported, cannot create virtual tables' ); - } - $db->query( 'CREATE VIRTUAL TABLE "foo" USING FTS3(foobar)' ); - - $db->duplicateTableStructure( 'foo', 'bar' ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "bar" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'bar' ) ), - 'Duplication of virtual tables' - ); - - $db->duplicateTableStructure( 'foo', 'baz', true ); - $this->assertEquals( 'CREATE VIRTUAL TABLE "baz" USING FTS3(foobar)', - $db->selectField( 'sqlite_master', 'sql', array( 'name' => 'baz' ) ), - "Can't create temporary virtual tables, should fall back to non-temporary duplication" - ); - } - - public function testDeleteJoin() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->query( 'CREATE TABLE a (a_1)', __METHOD__ ); - $db->query( 'CREATE TABLE b (b_1, b_2)', __METHOD__ ); - $db->insert( 'a', array( - array( 'a_1' => 1 ), - array( 'a_1' => 2 ), - array( 'a_1' => 3 ), - ), - __METHOD__ - ); - $db->insert( 'b', array( - array( 'b_1' => 2, 'b_2' => 'a' ), - array( 'b_1' => 3, 'b_2' => 'b' ), - ), - __METHOD__ - ); - $db->deleteJoin( 'a', 'b', 'a_1', 'b_1', array( 'b_2' => 'a' ), __METHOD__ ); - $res = $db->query( "SELECT * FROM a", __METHOD__ ); - $this->assertResultIs( array( - array( 'a_1' => 1 ), - array( 'a_1' => 3 ), - ), - $res - ); - } - - public function testEntireSchema() { - global $IP; - - $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" ); - if ( $result !== true ) { - $this->fail( $result ); - } - $this->assertTrue( true ); // avoid test being marked as incomplete due to lack of assertions - } - - /** - * Runs upgrades of older databases and compares results with current schema - * @todo: currently only checks list of tables - */ - public function testUpgrades() { - global $IP, $wgVersion; - - // Versions tested - $versions = array( - //'1.13', disabled for now, was totally screwed up - // SQLite wasn't included in 1.14 - '1.15', - '1.16', - '1.17', - '1.18', - ); - - // Mismatches for these columns we can safely ignore - $ignoredColumns = array( - 'user_newtalk.user_last_timestamp', // r84185 - ); - - $currentDB = new DatabaseSqliteStandalone( ':memory:' ); - $currentDB->sourceFile( "$IP/maintenance/tables.sql" ); - $currentTables = $this->getTables( $currentDB ); - sort( $currentTables ); - - foreach ( $versions as $version ) { - $versions = "upgrading from $version to $wgVersion"; - $db = $this->prepareDB( $version ); - $tables = $this->getTables( $db ); - $this->assertEquals( $currentTables, $tables, "Different tables $versions" ); - foreach ( $tables as $table ) { - $currentCols = $this->getColumns( $currentDB, $table ); - $cols = $this->getColumns( $db, $table ); - $this->assertEquals( - array_keys( $currentCols ), - array_keys( $cols ), - "Mismatching columns for table \"$table\" $versions" - ); - foreach ( $currentCols as $name => $column ) { - $fullName = "$table.$name"; - $this->assertEquals( - (bool)$column->pk, - (bool)$cols[$name]->pk, - "PRIMARY KEY status does not match for column $fullName $versions" - ); - if ( !in_array( $fullName, $ignoredColumns ) ) { - $this->assertEquals( - (bool)$column->notnull, - (bool)$cols[$name]->notnull, - "NOT NULL status does not match for column $fullName $versions" - ); - $this->assertEquals( - $column->dflt_value, - $cols[$name]->dflt_value, - "Default values does not match for column $fullName $versions" - ); - } - } - $currentIndexes = $this->getIndexes( $currentDB, $table ); - $indexes = $this->getIndexes( $db, $table ); - $this->assertEquals( - array_keys( $currentIndexes ), - array_keys( $indexes ), - "mismatching indexes for table \"$table\" $versions" - ); - } - $db->close(); - } - } - - public function testInsertIdType() { - $db = new DatabaseSqliteStandalone( ':memory:' ); - $this->assertInstanceOf( 'ResultWrapper', - $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ ), "Database creationg" ); - $this->assertTrue( $db->insert( 'a', array( 'a_1' => 10 ), __METHOD__ ), - "Insertion worked" ); - $this->assertEquals( "integer", gettype( $db->insertId() ), "Actual typecheck" ); - $this->assertTrue( $db->close(), "closing database" ); - } - - private function prepareDB( $version ) { - static $maint = null; - if ( $maint === null ) { - $maint = new FakeMaintenance(); - $maint->loadParamsAndArgs( null, array( 'quiet' => 1 ) ); - } - - global $IP; - $db = new DatabaseSqliteStandalone( ':memory:' ); - $db->sourceFile( "$IP/tests/phpunit/data/db/sqlite/tables-$version.sql" ); - $updater = DatabaseUpdater::newForDB( $db, false, $maint ); - $updater->doUpdates( array( 'core' ) ); - return $db; - } - - private function getTables( $db ) { - $list = array_flip( $db->listTables() ); - $excluded = array( - 'math', // moved out of core in 1.18 - 'trackbacks', // removed from core in 1.19 - 'searchindex', - 'searchindex_content', - 'searchindex_segments', - 'searchindex_segdir', - // FTS4 ready!!1 - 'searchindex_docsize', - 'searchindex_stat', - ); - foreach ( $excluded as $t ) { - unset( $list[$t] ); - } - $list = array_flip( $list ); - sort( $list ); - return $list; - } - - private function getColumns( $db, $table ) { - $cols = array(); - $res = $db->query( "PRAGMA table_info($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $col ) { - $cols[$col->name] = $col; - } - ksort( $cols ); - return $cols; - } - - private function getIndexes( $db, $table ) { - $indexes = array(); - $res = $db->query( "PRAGMA index_list($table)" ); - $this->assertNotNull( $res ); - foreach ( $res as $index ) { - $res2 = $db->query( "PRAGMA index_info({$index->name})" ); - $this->assertNotNull( $res2 ); - $index->columns = array(); - foreach ( $res2 as $col ) { - $index->columns[] = $col; - } - $indexes[$index->name] = $index; - } - ksort( $indexes ); - return $indexes; - } -} diff --git a/tests/phpunit/includes/db/DatabaseTest.php b/tests/phpunit/includes/db/DatabaseTest.php deleted file mode 100644 index 379ffb17..00000000 --- a/tests/phpunit/includes/db/DatabaseTest.php +++ /dev/null @@ -1,215 +0,0 @@ -db = wfGetDB( DB_MASTER ); - } - - function tearDown() { - if ( $this->functionTest ) { - $this->dropFunctions(); - $this->functionTest = false; - } - } - - function testAddQuotesNull() { - $check = "NULL"; - if ( $this->db->getType() === 'sqlite' || $this->db->getType() === 'oracle' ) { - $check = "''"; - } - $this->assertEquals( $check, $this->db->addQuotes( null ) ); - } - - function testAddQuotesInt() { - # returning just "1234" should be ok too, though... - # maybe - $this->assertEquals( - "'1234'", - $this->db->addQuotes( 1234 ) ); - } - - function testAddQuotesFloat() { - # returning just "1234.5678" would be ok too, though - $this->assertEquals( - "'1234.5678'", - $this->db->addQuotes( 1234.5678 ) ); - } - - function testAddQuotesString() { - $this->assertEquals( - "'string'", - $this->db->addQuotes( 'string' ) ); - } - - function testAddQuotesStringQuote() { - $check = "'string''s cause trouble'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "'string\'s cause trouble'"; - } - $this->assertEquals( - $check, - $this->db->addQuotes( "string's cause trouble" ) ); - } - - private function getSharedTableName( $table, $database, $prefix, $format = 'quoted' ) { - global $wgSharedDB, $wgSharedTables, $wgSharedPrefix; - - $oldName = $wgSharedDB; - $oldTables = $wgSharedTables; - $oldPrefix = $wgSharedPrefix; - - $wgSharedDB = $database; - $wgSharedTables = array( $table ); - $wgSharedPrefix = $prefix; - - $ret = $this->db->tableName( $table, $format ); - - $wgSharedDB = $oldName; - $wgSharedTables = $oldTables; - $wgSharedPrefix = $oldPrefix; - - return $ret; - } - - private function prefixAndQuote( $table, $database = null, $prefix = null, $format = 'quoted' ) { - if ( $this->db->getType() === 'sqlite' || $format !== 'quoted' ) { - $quote = ''; - } elseif ( $this->db->getType() === 'mysql' ) { - $quote = '`'; - } else { - $quote = '"'; - } - - if ( $database !== null ) { - $database = $quote . $database . $quote . '.'; - } - - if ( $prefix === null ) { - $prefix = $this->dbPrefix(); - } - - return $database . $quote . $prefix . $table . $quote; - } - - function testTableNameLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename' ), - $this->db->tableName( 'tablename' ) - ); - } - - function testTableNameRawLocal() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', null, null, 'raw' ), - $this->db->tableName( 'tablename', 'raw' ) - ); - } - - function testTableNameShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null ) - ); - } - - function testTableNameRawShared() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', 'sh_', 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', 'sh_', 'raw' ) - ); - - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'sharedatabase', null, 'raw' ), - $this->getSharedTableName( 'tablename', 'sharedatabase', null, 'raw' ) - ); - } - - function testTableNameForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '' ), - $this->db->tableName( 'databasename.tablename' ) - ); - } - - function testTableNameRawForeign() { - $this->assertEquals( - $this->prefixAndQuote( 'tablename', 'databasename', '', 'raw' ), - $this->db->tableName( 'databasename.tablename', 'raw' ) - ); - } - - function testFillPreparedEmpty() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM interwiki', array() ); - $this->assertEquals( - "SELECT * FROM interwiki", - $sql ); - } - - function testFillPreparedQuestion() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', - array( 4, "Snicker's_paradox" ) ); - - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker''s_paradox'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'"; - } - $this->assertEquals( $check, $sql ); - } - - function testFillPreparedBang() { - $sql = $this->db->fillPrepared( - 'SELECT user_id FROM ! WHERE user_name=?', - array( '"user"', "Slash's Dot" ) ); - - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash''s Dot'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'"; - } - $this->assertEquals( $check, $sql ); - } - - function testFillPreparedRaw() { - $sql = $this->db->fillPrepared( - "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", - array( '"user"', "Slash's Dot" ) ); - $this->assertEquals( - "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", - $sql ); - } - - /** - * @group Broken - */ - function testStoredFunctions() { - if ( !in_array( wfGetDB( DB_MASTER )->getType(), array( 'mysql', 'postgres' ) ) ) { - $this->markTestSkipped( 'MySQL or Postgres required' ); - } - global $IP; - $this->dropFunctions(); - $this->functionTest = true; - $this->assertTrue( $this->db->sourceFile( "$IP/tests/phpunit/data/db/{$this->db->getType()}/functions.sql" ) ); - $res = $this->db->query( 'SELECT mw_test_function() AS test', __METHOD__ ); - $this->assertEquals( 42, $res->fetchObject()->test ); - } - - private function dropFunctions() { - $this->db->query( 'DROP FUNCTION IF EXISTS mw_test_function' - . ( $this->db->getType() == 'postgres' ? '()' : '' ) - ); - } -} - - diff --git a/tests/phpunit/includes/db/ORMRowTest.php b/tests/phpunit/includes/db/ORMRowTest.php deleted file mode 100644 index 9dcaf2b3..00000000 --- a/tests/phpunit/includes/db/ORMRowTest.php +++ /dev/null @@ -1,234 +0,0 @@ - - */ -abstract class ORMRowTest extends \MediaWikiTestCase { - - /** - * @since 1.20 - * @return string - */ - protected abstract function getRowClass(); - - /** - * @since 1.20 - * @return IORMTable - */ - protected abstract function getTableInstance(); - - /** - * @since 1.20 - * @return array - */ - public abstract function constructorTestProvider(); - - /** - * @since 1.20 - * @param IORMRow $row - * @param array $data - */ - protected function verifyFields( IORMRow $row, array $data ) { - foreach ( array_keys( $data ) as $fieldName ) { - $this->assertEquals( $data[$fieldName], $row->getField( $fieldName ) ); - } - } - - /** - * @since 1.20 - * @param array $data - * @param boolean $loadDefaults - * @return IORMRow - */ - protected function getRowInstance( array $data, $loadDefaults ) { - $class = $this->getRowClass(); - return new $class( $this->getTableInstance(), $data, $loadDefaults ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockValues() { - return array( - 'id' => 1, - 'str' => 'foobar4645645', - 'int' => 42, - 'float' => 4.2, - 'bool' => true, - 'array' => array( 42, 'foobar' ), - 'blob' => new stdClass() - ); - } - - /** - * @since 1.20 - * @return array - */ - protected function getMockFields() { - $mockValues = $this->getMockValues(); - $mockFields = array(); - - foreach ( $this->getTableInstance()->getFields() as $name => $type ) { - if ( $name !== 'id' ) { - $mockFields[$name] = $mockValues[$type]; - } - } - - return $mockFields; - } - - /** - * @since 1.20 - * @return array of IORMRow - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->constructorTestProvider() as $arguments ) { - $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) ); - } - - return $instances; - } - - /** - * @dataProvider constructorTestProvider - */ - public function testConstructor( array $data, $loadDefaults ) { - $this->verifyFields( $this->getRowInstance( $data, $loadDefaults ), $data ); - } - - /** - * @dataProvider constructorTestProvider - */ - public function testSave( array $data, $loadDefaults ) { - $item = $this->getRowInstance( $data, $loadDefaults ); - - $this->assertTrue( $item->save() ); - - $this->assertTrue( $item->hasIdField() ); - $this->assertTrue( is_integer( $item->getId() ) ); - - $id = $item->getId(); - - $this->assertTrue( $item->save() ); - - $this->assertEquals( $id, $item->getId() ); - - $this->verifyFields( $item, $data ); - } - - /** - * @dataProvider constructorTestProvider - */ - public function testRemove( array $data, $loadDefaults ) { - $item = $this->getRowInstance( $data, $loadDefaults ); - - $this->assertTrue( $item->save() ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->assertTrue( $item->save() ); - - $this->verifyFields( $item, $data ); - - $this->assertTrue( $item->remove() ); - - $this->assertFalse( $item->hasIdField() ); - - $this->verifyFields( $item, $data ); - } - - /** - * @dataProvider instanceProvider - */ - public function testSetField( IORMRow $item ) { - foreach ( $this->getMockFields() as $name => $value ) { - $item->setField( $name, $value ); - $this->assertEquals( $value, $item->getField( $name ) ); - } - } - - /** - * @since 1.20 - * @param array $expected - * @param IORMRow $item - */ - protected function assertFieldValues( array $expected, IORMRow $item ) { - foreach ( $expected as $name => $type ) { - if ( $name !== 'id' ) { - $this->assertEquals( $expected[$name], $item->getField( $name ) ); - } - } - } - - /** - * @dataProvider instanceProvider - */ - public function testSetFields( IORMRow $item ) { - $originalValues = $item->getFields(); - - $item->setFields( array(), false ); - - foreach ( $item->getTable()->getFields() as $name => $type ) { - $originalHas = array_key_exists( $name, $originalValues ); - $newHas = $item->hasField( $name ); - - $this->assertEquals( $originalHas, $newHas ); - - if ( $originalHas && $newHas ) { - $this->assertEquals( $originalValues[$name], $item->getField( $name ) ); - } - } - - $mockFields = $this->getMockFields(); - - $item->setFields( $mockFields, false ); - - $this->assertFieldValues( $originalValues, $item ); - - $item->setFields( $mockFields, true ); - - $this->assertFieldValues( $mockFields, $item ); - } - - // TODO: test all of the methods! - -} \ No newline at end of file diff --git a/tests/phpunit/includes/db/TestORMRowTest.php b/tests/phpunit/includes/db/TestORMRowTest.php deleted file mode 100644 index afd1cb80..00000000 --- a/tests/phpunit/includes/db/TestORMRowTest.php +++ /dev/null @@ -1,174 +0,0 @@ - - */ -require_once __DIR__ . "/ORMRowTest.php"; - -class TestORMRowTest extends ORMRowTest { - - /** - * @since 1.20 - * @return string - */ - protected function getRowClass() { - return 'TestORMRow'; - } - - /** - * @since 1.20 - * @return IORMTable - */ - protected function getTableInstance() { - return TestORMTable::singleton(); - } - - public function setUp() { - parent::setUp(); - - $dbw = wfGetDB( DB_MASTER ); - - $isSqlite = $GLOBALS['wgDBtype'] === 'sqlite'; - - $idField = $isSqlite ? 'INTEGER' : 'INT unsigned'; - $primaryKey = $isSqlite ? 'PRIMARY KEY AUTOINCREMENT' : 'auto_increment PRIMARY KEY'; - - $dbw->query( - 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '( - test_id ' . $idField . ' NOT NULL ' . $primaryKey . ', - test_name VARCHAR(255) NOT NULL, - test_age TINYINT unsigned NOT NULL, - test_height FLOAT NOT NULL, - test_awesome TINYINT unsigned NOT NULL, - test_stuff BLOB NOT NULL, - test_moarstuff BLOB NOT NULL, - test_time varbinary(14) NOT NULL - );' - ); - } - - public function constructorTestProvider() { - return array( - array( - array( - 'name' => 'Foobar', - 'age' => 42, - 'height' => 9000.1, - 'awesome' => true, - 'stuff' => array( 13, 11, 7, 5, 3, 2 ), - 'moarstuff' => (object)array( 'foo' => 'bar', 'bar' => array( 4, 2 ), 'baz' => true ) - ), - true - ), - ); - } - -} - -class TestORMRow extends ORMRow {} - -class TestORMTable extends ORMTable { - - /** - * Returns the name of the database table objects of this type are stored in. - * - * @since 1.20 - * - * @return string - */ - public function getName() { - return 'orm_test'; - } - - /** - * Returns the name of a IORMRow implementing class that - * represents single rows in this table. - * - * @since 1.20 - * - * @return string - */ - public function getRowClass() { - return 'TestORMRow'; - } - - /** - * Returns an array with the fields and their types this object contains. - * This corresponds directly to the fields in the database, without prefix. - * - * field name => type - * - * Allowed types: - * * id - * * str - * * int - * * float - * * bool - * * array - * * blob - * - * @since 1.20 - * - * @return array - */ - public function getFields() { - return array( - 'id' => 'id', - 'name' => 'str', - 'age' => 'int', - 'height' => 'float', - 'awesome' => 'bool', - 'stuff' => 'array', - 'moarstuff' => 'blob', - 'time' => 'int', // TS_MW - ); - } - - /** - * Gets the db field prefix. - * - * @since 1.20 - * - * @return string - */ - protected function getFieldPrefix() { - return 'test_'; - } - - -} diff --git a/tests/phpunit/includes/debug/MWDebugTest.php b/tests/phpunit/includes/debug/MWDebugTest.php deleted file mode 100644 index 246b2918..00000000 --- a/tests/phpunit/includes/debug/MWDebugTest.php +++ /dev/null @@ -1,68 +0,0 @@ -assertEquals( array( array( - 'msg' => 'logging a string', - 'type' => 'log', - 'caller' => __METHOD__ , - ) ), - MWDebug::getLog() - ); - } - - function testAddWarning() { - MWDebug::warning( 'Warning message' ); - $this->assertEquals( array( array( - 'msg' => 'Warning message', - 'type' => 'warn', - 'caller' => 'MWDebugTest::testAddWarning', - ) ), - MWDebug::getLog() - ); - } - - function testAvoidDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 1, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } - - function testAvoidNonConsecutivesDuplicateDeprecations() { - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - MWDebug::warning( 'some warning' ); - MWDebug::log( 'we could have logged something too' ); - // Another deprecation - MWDebug::deprecated( 'wfOldFunction', '1.0', 'component' ); - - // assertCount() not available on WMF integration server - $this->assertEquals( 3, - count( MWDebug::getLog() ), - "Only one deprecated warning per function should be kept" - ); - } -} diff --git a/tests/phpunit/includes/filerepo/FileBackendTest.php b/tests/phpunit/includes/filerepo/FileBackendTest.php deleted file mode 100644 index a2dc5c6c..00000000 --- a/tests/phpunit/includes/filerepo/FileBackendTest.php +++ /dev/null @@ -1,1868 +0,0 @@ -getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $this->singleBackend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - break; - } - } - $useConfig['name'] = 'localtesting'; // swap name - $useConfig['shardViaHashLevels'] = array( // test sharding - 'unittest-cont1' => array( 'levels' => 1, 'base' => 16, 'repeat' => 1 ) - ); - $class = $useConfig['class']; - self::$backendToUse = new $class( $useConfig ); - $this->singleBackend = self::$backendToUse; - } - } else { - $this->singleBackend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'fsLockManager', - #'parallelize' => 'implicit', - 'containerPaths' => array( - 'unittest-cont1' => "{$tmpPrefix}-localtesting-cont1", - 'unittest-cont2' => "{$tmpPrefix}-localtesting-cont2" ) - ) ); - } - $this->multiBackend = new FileBackendMultiWrite( array( - 'name' => 'localtesting', - 'lockManager' => 'fsLockManager', - 'parallelize' => 'implicit', - 'backends' => array( - array( - 'name' => 'localmutlitesting1', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti1-cont1", - 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti1-cont2" ), - 'isMultiMaster' => false - ), - array( - 'name' => 'localmutlitesting2', - 'class' => 'FSFileBackend', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1", - 'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ), - 'isMultiMaster' => true - ) - ) - ) ); - $this->filesToPrune = array(); - } - - private function baseStorePath() { - return 'mwstore://localtesting'; - } - - private function backendClass() { - return get_class( $this->backend ); - } - - /** - * @dataProvider provider_testIsStoragePath - */ - public function testIsStoragePath( $path, $isStorePath ) { - $this->assertEquals( $isStorePath, FileBackend::isStoragePath( $path ), - "FileBackend::isStoragePath on path '$path'" ); - } - - function provider_testIsStoragePath() { - return array( - array( 'mwstore://', true ), - array( 'mwstore://backend', true ), - array( 'mwstore://backend/container', true ), - array( 'mwstore://backend/container/', true ), - array( 'mwstore://backend/container/path', true ), - array( 'mwstore://backend//container/', true ), - array( 'mwstore://backend//container//', true ), - array( 'mwstore://backend//container//path', true ), - array( 'mwstore:///', true ), - array( 'mwstore:/', false ), - array( 'mwstore:', false ), - ); - } - - /** - * @dataProvider provider_testSplitStoragePath - */ - public function testSplitStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::splitStoragePath( $path ), - "FileBackend::splitStoragePath on path '$path'" ); - } - - function provider_testSplitStoragePath() { - return array( - array( 'mwstore://backend/container', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/', array( 'backend', 'container', '' ) ), - array( 'mwstore://backend/container/path', array( 'backend', 'container', 'path' ) ), - array( 'mwstore://backend/container//path', array( 'backend', 'container', '/path' ) ), - array( 'mwstore://backend//container/path', array( null, null, null ) ), - array( 'mwstore://backend//container//path', array( null, null, null ) ), - array( 'mwstore://', array( null, null, null ) ), - array( 'mwstore://backend', array( null, null, null ) ), - array( 'mwstore:///', array( null, null, null ) ), - array( 'mwstore:/', array( null, null, null ) ), - array( 'mwstore:', array( null, null, null ) ) - ); - } - - /** - * @dataProvider provider_normalizeStoragePath - */ - public function testNormalizeStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::normalizeStoragePath( $path ), - "FileBackend::normalizeStoragePath on path '$path'" ); - } - - function provider_normalizeStoragePath() { - return array( - array( 'mwstore://backend/container', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container//path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container///path//to///obj', 'mwstore://backend/container/path/to/obj', - array( 'mwstore://', null ), - array( 'mwstore://backend', null ), - array( 'mwstore://backend//container/path', null ), - array( 'mwstore://backend//container//path', null ), - array( 'mwstore:///', null ), - array( 'mwstore:/', null ), - array( 'mwstore:', null ), ) - ); - } - - /** - * @dataProvider provider_testParentStoragePath - */ - public function testParentStoragePath( $path, $res ) { - $this->assertEquals( $res, FileBackend::parentStoragePath( $path ), - "FileBackend::parentStoragePath on path '$path'" ); - } - - function provider_testParentStoragePath() { - return array( - array( 'mwstore://backend/container/path/to/obj', 'mwstore://backend/container/path/to' ), - array( 'mwstore://backend/container/path/to', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container/path', 'mwstore://backend/container' ), - array( 'mwstore://backend/container', null ), - array( 'mwstore://backend/container/path/to/obj/', 'mwstore://backend/container/path/to' ), - array( 'mwstore://backend/container/path/to/', 'mwstore://backend/container/path' ), - array( 'mwstore://backend/container/path/', 'mwstore://backend/container' ), - array( 'mwstore://backend/container/', null ), - ); - } - - /** - * @dataProvider provider_testExtensionFromPath - */ - public function testExtensionFromPath( $path, $res ) { - $this->assertEquals( $res, FileBackend::extensionFromPath( $path ), - "FileBackend::extensionFromPath on path '$path'" ); - } - - function provider_testExtensionFromPath() { - return array( - array( 'mwstore://backend/container/path.txt', 'txt' ), - array( 'mwstore://backend/container/path.svg.png', 'png' ), - array( 'mwstore://backend/container/path', '' ), - array( 'mwstore://backend/container/path.', '' ), - ); - } - - /** - * @dataProvider provider_testStore - */ - public function testStore( $op ) { - $this->filesToPrune[] = $op['src']; - - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestStore( $op ); - $this->filesToPrune[] = $op['src']; # avoid file leaking - $this->tearDownFiles(); - } - - private function doTestStore( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - file_put_contents( $source, "Unit test file" ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->store( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Store from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Store from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Store from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, file_exists( $source ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists ($backendName)." ); - - $this->assertEquals( filesize( $source ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = FSFile::getPropsFromPath( $source ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - public function provider_testStore() { - $cases = array(); - - $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - $toPath = $this->baseStorePath() . '/unittest-cont1/e/fun/obj1.txt'; - $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath ); - $cases[] = array( - $op, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $tmpName, // source - $toPath, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testCopy - */ - public function testCopy( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCopy( $op ); - $this->tearDownFiles(); - } - - private function doTestCopy( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - - $this->assertGoodStatus( $status, - "Copy from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Copy from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Copy from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after copy ($backendName)." ); - - $this->assertEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( $props1, $props2, - "Source and destination have the same props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public function provider_testCopy() { - $cases = array(); - - $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testMove - */ - public function testMove( $op ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestMove( $op ); - $this->tearDownFiles(); - } - - private function doTestMove( $op ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - if ( isset( $op['overwrite'] ) || isset( $op['overwriteSame'] ) ) { - $this->backend->copy( $op ); - } - - $status = $this->backend->doOperation( $op ); - $this->assertGoodStatus( $status, - "Move from $source to $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Move from $source to $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Move from $source to $dest has proper 'success' field in Status ($backendName)." ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not still exists ($backendName)." ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after move ($backendName)." ); - - $this->assertNotEquals( - $this->backend->getFileSize( array( 'src' => $source ) ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $props2 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( false, $props1['fileExists'], - "Source file does not exist accourding to props ($backendName)." ); - $this->assertEquals( true, $props2['fileExists'], - "Destination file exists accourding to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source, $dest ) ); - } - - public function provider_testMove() { - $cases = array(); - - $source = $this->baseStorePath() . '/unittest-cont1/e/file.txt'; - $dest = $this->baseStorePath() . '/unittest-cont2/a/fileMoved.txt'; - - $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest ); - $cases[] = array( - $op, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - $op2 = $op; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - $source, // source - $dest, // dest - ); - - return $cases; - } - - /** - * @dataProvider provider_testDelete - */ - public function testDelete( $op, $withSource, $okStatus ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDelete( $op, $withSource, $okStatus ); - $this->tearDownFiles(); - } - - private function doTestDelete( $op, $withSource, $okStatus ) { - $backendName = $this->backendClass(); - - $source = $op['src']; - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - if ( $withSource ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Deletion of file at $source succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Deletion of file at $source succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Deletion of file at $source has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Deletion of file at $source failed ($backendName)." ); - } - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ), - "Source file $source does not exist after move ($backendName)." ); - - $this->assertFalse( - $this->backend->getFileSize( array( 'src' => $source ) ), - "Source file $source has correct size (false) ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); - $this->assertFalse( $props1['fileExists'], - "Source file $source does not exist according to props ($backendName)." ); - - $this->assertBackendPathsConsistent( array( $source ) ); - } - - public function provider_testDelete() { - $cases = array(); - - $source = $this->baseStorePath() . '/unittest-cont1/e/myfacefile.txt'; - - $op = array( 'op' => 'delete', 'src' => $source ); - $cases[] = array( - $op, // operation - true, // with source - true // succeeds - ); - - $cases[] = array( - $op, // operation - false, // without source - false // fails - ); - - $op['ignoreMissingSource'] = true; - $cases[] = array( - $op, // operation - false, // without source - true // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testCreate - */ - public function testCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestCreate( $op, $alreadyExists, $okStatus, $newSize ); - $this->tearDownFiles(); - } - - private function doTestCreate( $op, $alreadyExists, $okStatus, $newSize ) { - $backendName = $this->backendClass(); - - $dest = $op['dst']; - $this->prepare( array( 'dir' => dirname( $dest ) ) ); - - $oldText = 'blah...blah...waahwaah'; - if ( $alreadyExists ) { - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) ); - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded ($backendName)." ); - } - - $status = $this->backend->doOperation( $op ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of file at $dest succeeded ($backendName)." ); - $this->assertEquals( array( 0 => true ), $status->success, - "Creation of file at $dest has proper 'success' field in Status ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of file at $dest failed ($backendName)." ); - } - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), - "Destination file $dest exists after creation ($backendName)." ); - - $props1 = $this->backend->getFileProps( array( 'src' => $dest ) ); - $this->assertEquals( true, $props1['fileExists'], - "Destination file $dest exists according to props ($backendName)." ); - if ( $okStatus ) { // file content is what we saved - $this->assertEquals( $newSize, $props1['size'], - "Destination file $dest has expected size according to props ($backendName)." ); - $this->assertEquals( $newSize, - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has correct size ($backendName)." ); - } else { // file content is some other previous text - $this->assertEquals( strlen( $oldText ), $props1['size'], - "Destination file $dest has original size according to props ($backendName)." ); - $this->assertEquals( strlen( $oldText ), - $this->backend->getFileSize( array( 'src' => $dest ) ), - "Destination file $dest has original size according to props ($backendName)." ); - } - - $this->assertBackendPathsConsistent( array( $dest ) ); - } - - /** - * @dataProvider provider_testCreate - */ - public function provider_testCreate() { - $cases = array(); - - $dest = $this->baseStorePath() . '/unittest-cont2/a/myspacefile.txt'; - - $op = array( 'op' => 'create', 'content' => 'test test testing', 'dst' => $dest ); - $cases[] = array( - $op, // operation - false, // no dest already exists - true, // succeeds - strlen( $op['content'] ) - ); - - $op2 = $op; - $op2['content'] = "\n"; - $cases[] = array( - $op2, // operation - false, // no dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "fsf\n waf 3kt"; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // fails - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "egm'g gkpe gpqg eqwgwqg"; - $op2['overwrite'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - true, // succeeds - strlen( $op2['content'] ) - ); - - $op2 = $op; - $op2['content'] = "39qjmg3-qg"; - $op2['overwriteSame'] = true; - $cases[] = array( - $op2, // operation - true, // dest already exists - false, // succeeds - strlen( $op2['content'] ) - ); - - return $cases; - } - - public function testDoQuickOperations() { - $this->backend = $this->singleBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestDoQuickOperations(); - $this->tearDownFiles(); - } - - private function doTestDoQuickOperations() { - $backendName = $this->backendClass(); - - $base = $this->baseStorePath(); - $files = array( - "$base/unittest-cont1/e/fileA.a", - "$base/unittest-cont1/e/fileB.a", - "$base/unittest-cont1/e/fileC.a" - ); - $ops = array(); - $purgeOps = array(); - foreach ( $files as $path ) { - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - $this->assertGoodStatus( $status, - "Preparing $path succeeded without warnings ($backendName)." ); - $ops[] = array( 'op' => 'create', 'dst' => $path, 'content' => mt_rand(0,50000) ); - $purgeOps[] = array( 'op' => 'delete', 'src' => $path ); - } - $purgeOps[] = array( 'op' => 'null' ); - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); - - foreach ( $files as $file ) { - $this->assertTrue( $this->backend->fileExists( array( 'src' => $file ) ), - "File $file exists." ); - } - - $status = $this->backend->doQuickOperations( $purgeOps ); - $this->assertGoodStatus( $status, - "Quick deletion of source files succeeded ($backendName)." ); - - foreach ( $files as $file ) { - $this->assertFalse( $this->backend->fileExists( array( 'src' => $file ) ), - "File $file purged." ); - } - } - - /** - * @dataProvider provider_testConcatenate - */ - public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $this->filesToPrune[] = $op['dst']; - - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ); - $this->filesToPrune[] = $op['dst']; # avoid file leaking - $this->tearDownFiles(); - } - - private function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) { - $backendName = $this->backendClass(); - - $expContent = ''; - // Create sources - $ops = array(); - foreach ( $srcs as $i => $source ) { - $this->prepare( array( 'dir' => dirname( $source ) ) ); - $ops[] = array( - 'op' => 'create', // operation - 'dst' => $source, // source - 'content' => $srcsContent[$i] - ); - $expContent .= $srcsContent[$i]; - } - $status = $this->backend->doOperations( $ops ); - - $this->assertGoodStatus( $status, - "Creation of source files succeeded ($backendName)." ); - - $dest = $params['dst']; - if ( $alreadyExists ) { - $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false; - $this->assertEquals( true, $ok, - "Creation of file at $dest succeeded ($backendName)." ); - } else { - $ok = file_put_contents( $dest, '' ) !== false; - $this->assertEquals( true, $ok, - "Creation of 0-byte file at $dest succeeded ($backendName)." ); - } - - // Combine the files into one - $status = $this->backend->concatenate( $params ); - if ( $okStatus ) { - $this->assertGoodStatus( $status, - "Creation of concat file at $dest succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of concat file at $dest succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Creation of concat file at $dest failed ($backendName)." ); - } - - if ( $okStatus ) { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after creation ($backendName)." ); - } else { - $this->assertEquals( true, is_file( $dest ), - "Dest concat file $dest exists after failed creation ($backendName)." ); - } - - $contents = file_get_contents( $dest ); - $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." ); - - if ( $okStatus ) { - $this->assertEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } else { - $this->assertNotEquals( $expContent, $contents, - "Concat file at $dest has correct contents ($backendName)." ); - } - } - - function provider_testConcatenate() { - $cases = array(); - - $rand = mt_rand( 0, 2000000000 ) . time(); - $dest = wfTempDir() . "/randomfile!$rand.txt"; - $srcs = array( - $this->baseStorePath() . '/unittest-cont1/e/file1.txt', - $this->baseStorePath() . '/unittest-cont1/e/file2.txt', - $this->baseStorePath() . '/unittest-cont1/e/file3.txt', - $this->baseStorePath() . '/unittest-cont1/e/file4.txt', - $this->baseStorePath() . '/unittest-cont1/e/file5.txt', - $this->baseStorePath() . '/unittest-cont1/e/file6.txt', - $this->baseStorePath() . '/unittest-cont1/e/file7.txt', - $this->baseStorePath() . '/unittest-cont1/e/file8.txt', - $this->baseStorePath() . '/unittest-cont1/e/file9.txt', - $this->baseStorePath() . '/unittest-cont1/e/file10.txt' - ); - $content = array( - 'egfage', - 'ageageag', - 'rhokohlr', - 'shgmslkg', - 'kenga', - 'owagmal', - 'kgmae', - 'g eak;g', - 'lkaem;a', - 'legma' - ); - $params = array( 'srcs' => $srcs, 'dst' => $dest ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - false, // no dest already exists - true, // succeeds - ); - - $cases[] = array( - $params, // operation - $srcs, // sources - $content, // content for each source - true, // dest already exists - false, // succeeds - ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileStat - */ - public function testGetFileStat( $path, $content, $alreadyExists ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileStat( $path, $content, $alreadyExists ); - $this->tearDownFiles(); - } - - private function doTestGetFileStat( $path, $content, $alreadyExists ) { - $backendName = $this->backendClass(); - - if ( $alreadyExists ) { - $this->prepare( array( 'dir' => dirname( $path ) ) ); - $status = $this->create( array( 'dst' => $path, 'content' => $content ) ); - $this->assertGoodStatus( $status, - "Creation of file at $path succeeded ($backendName)." ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $size = $stat['size']; - $time = $stat['mtime']; - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - $this->assertTrue( abs( time() - wfTimestamp( TS_UNIX, $time ) ) < 10, - "Correct file timestamp of '$path'" ); - - $this->backend->clearCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - - $this->backend->preloadCache( array( $path ) ); - - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - - $this->assertEquals( strlen( $content ), $size, - "Correct file size of '$path'" ); - } else { - $size = $this->backend->getFileSize( array( 'src' => $path ) ); - $time = $this->backend->getFileTimestamp( array( 'src' => $path ) ); - $stat = $this->backend->getFileStat( array( 'src' => $path ) ); - - $this->assertFalse( $size, "Correct file size of '$path'" ); - $this->assertFalse( $time, "Correct file timestamp of '$path'" ); - $this->assertFalse( $stat, "Correct file stat of '$path'" ); - } - } - - function provider_testGetFileStat() { - $cases = array(); - - $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "", true ); - $cases[] = array( "$base/unittest-cont1/e/b/some-diff_file.txt", null, false ); - - return $cases; - } - - /** - * @dataProvider provider_testGetFileContents - */ - public function testGetFileContents( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileContents( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetFileContents( $source, $content ) { - $backendName = $this->backendClass(); - - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content, 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of file at $source succeeded with OK status ($backendName)." ); - - $newContents = $this->backend->getFileContents( array( 'src' => $source, 'latest' => 1 ) ); - $this->assertNotEquals( false, $newContents, - "Read of file at $source succeeded ($backendName)." ); - - $this->assertEquals( $content, $newContents, - "Contents read match data at $source ($backendName)." ); - } - - function provider_testGetFileContents() { - $cases = array(); - - $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/b/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/b/some-other_file.txt", "more file contents" ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalCopy - */ - public function testGetLocalCopy( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalCopy( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalCopy( $source, $content ) { - $backendName = $this->backendClass(); - - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - $status = $this->backend->doOperation( - array( 'op' => 'create', 'content' => $content, 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - $tmpFile = $this->backend->getLocalCopy( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." ); - } - - function provider_testGetLocalCopy() { - $cases = array(); - - $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - - return $cases; - } - - /** - * @dataProvider provider_testGetLocalReference - */ - public function testGetLocalReference( $source, $content ) { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetLocalReference( $source, $content ); - $this->tearDownFiles(); - } - - private function doTestGetLocalReference( $source, $content ) { - $backendName = $this->backendClass(); - - $this->prepare( array( 'dir' => dirname( $source ) ) ); - - $status = $this->create( array( 'content' => $content, 'dst' => $source ) ); - $this->assertGoodStatus( $status, - "Creation of file at $source succeeded ($backendName)." ); - - $tmpFile = $this->backend->getLocalReference( array( 'src' => $source ) ); - $this->assertNotNull( $tmpFile, - "Creation of local copy of $source succeeded ($backendName)." ); - - $contents = file_get_contents( $tmpFile->getPath() ); - $this->assertNotEquals( false, $contents, "Local copy of $source exists ($backendName)." ); - } - - function provider_testGetLocalReference() { - $cases = array(); - - $base = $this->baseStorePath(); - $cases[] = array( "$base/unittest-cont1/e/a/z/some_file.txt", "some file contents" ); - $cases[] = array( "$base/unittest-cont1/e/a/some-other_file.txt", "more file contents" ); - - return $cases; - } - - /** - * @dataProvider provider_testPrepareAndClean - */ - public function testPrepareAndClean( $path, $isOK ) { - $this->backend = $this->singleBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestPrepareAndClean( $path, $isOK ); - $this->tearDownFiles(); - } - - function provider_testPrepareAndClean() { - $base = $this->baseStorePath(); - return array( - array( "$base/unittest-cont1/e/a/z/some_file1.txt", true ), - array( "$base/unittest-cont2/a/z/some_file2.txt", true ), - # Specific to FS backend with no basePath field set - #array( "$base/unittest-cont3/a/z/some_file3.txt", false ), - ); - } - - private function doTestPrepareAndClean( $path, $isOK ) { - $backendName = $this->backendClass(); - - $status = $this->prepare( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Preparing dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Preparing dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Preparing dir $path failed ($backendName)." ); - } - - $status = $this->backend->clean( array( 'dir' => dirname( $path ) ) ); - if ( $isOK ) { - $this->assertGoodStatus( $status, - "Cleaning dir $path succeeded without warnings ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Cleaning dir $path succeeded ($backendName)." ); - } else { - $this->assertEquals( false, $status->isOK(), - "Cleaning dir $path failed ($backendName)." ); - } - } - - public function testRecursiveClean() { - $this->backend = $this->singleBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->doTestRecursiveClean(); - $this->tearDownFiles(); - } - - private function doTestRecursiveClean() { - $backendName = $this->backendClass(); - - $base = $this->baseStorePath(); - $dirs = array( - "$base/unittest-cont1/e/a", - "$base/unittest-cont1/e/a/b", - "$base/unittest-cont1/e/a/b/c", - "$base/unittest-cont1/e/a/b/c/d0", - "$base/unittest-cont1/e/a/b/c/d1", - "$base/unittest-cont1/e/a/b/c/d2", - "$base/unittest-cont1/e/a/b/c/d0/1", - "$base/unittest-cont1/e/a/b/c/d0/2", - "$base/unittest-cont1/e/a/b/c/d1/3", - "$base/unittest-cont1/e/a/b/c/d1/4", - "$base/unittest-cont1/e/a/b/c/d2/5", - "$base/unittest-cont1/e/a/b/c/d2/6" - ); - foreach ( $dirs as $dir ) { - $status = $this->prepare( array( 'dir' => $dir ) ); - $this->assertGoodStatus( $status, - "Preparing dir $dir succeeded without warnings ($backendName)." ); - } - - if ( $this->backend instanceof FSFileBackend ) { - foreach ( $dirs as $dir ) { - $this->assertEquals( true, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir exists ($backendName)." ); - } - } - - $status = $this->backend->clean( - array( 'dir' => "$base/unittest-cont1", 'recursive' => 1 ) ); - $this->assertGoodStatus( $status, - "Recursive cleaning of dir $dir succeeded without warnings ($backendName)." ); - - foreach ( $dirs as $dir ) { - $this->assertEquals( false, $this->backend->directoryExists( array( 'dir' => $dir ) ), - "Dir $dir no longer exists ($backendName)." ); - } - } - - // @TODO: testSecure - - public function testDoOperations() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperations(); - $this->tearDownFiles(); - } - - private function doTestDoOperations() { - $base = $this->baseStorePath(); - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: (file:) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 13, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - public function testDoOperationsPipeline() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsPipeline(); - $this->tearDownFiles(); - } - - // concurrency orientated - private function doTestDoOperationsPipeline() { - $base = $this->baseStorePath(); - - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - - $tmpNameA = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameA, $fileAContents ); - $tmpNameB = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameB, $fileBContents ); - $tmpNameC = TempFSFile::factory( "unittests_", 'txt' )->getPath(); - file_put_contents( $tmpNameC, $fileCContents ); - - $this->filesToPrune[] = $tmpNameA; # avoid file leaking - $this->filesToPrune[] = $tmpNameB; # avoid file leaking - $this->filesToPrune[] = $tmpNameC; # avoid file leaking - - $fileA = "$base/unittest-cont1/e/a/b/fileA.txt"; - $fileB = "$base/unittest-cont1/e/a/b/fileB.txt"; - $fileC = "$base/unittest-cont1/e/a/b/fileC.txt"; - $fileD = "$base/unittest-cont1/e/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->prepare( array( 'dir' => dirname( $fileD ) ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'store', 'src' => $tmpNameA, 'dst' => $fileA, 'overwriteSame' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameB, 'dst' => $fileB, 'overwrite' => 1 ), - array( 'op' => 'store', 'src' => $tmpNameC, 'dst' => $fileC, 'overwrite' => 1 ), - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: (file:) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileD, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileA, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwrite' => 1 ), - // Does nothing - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Does nothing - array( 'op' => 'null' ), - // Does nothing - ) ); - - $this->assertGoodStatus( $status, "Operation batch succeeded" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 16, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileC ) ), - "Correct file contents of $fileC" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileC ) ), - "Correct file size of $fileC" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileC ) ), - "Correct file SHA-1 of $fileC" ); - } - - public function testDoOperationsFailing() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestDoOperationsFailing(); - $this->tearDownFiles(); - } - - private function doTestDoOperationsFailing() { - $base = $this->baseStorePath(); - - $fileA = "$base/unittest-cont2/a/b/fileA.txt"; - $fileAContents = '3tqtmoeatmn4wg4qe-mg3qt3 tq'; - $fileB = "$base/unittest-cont2/a/b/fileB.txt"; - $fileBContents = 'g-jmq3gpqgt3qtg q3GT '; - $fileC = "$base/unittest-cont2/a/b/fileC.txt"; - $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag'; - $fileD = "$base/unittest-cont2/a/b/fileD.txt"; - - $this->prepare( array( 'dir' => dirname( $fileA ) ) ); - $this->create( array( 'dst' => $fileA, 'content' => $fileAContents ) ); - $this->prepare( array( 'dir' => dirname( $fileB ) ) ); - $this->create( array( 'dst' => $fileB, 'content' => $fileBContents ) ); - $this->prepare( array( 'dir' => dirname( $fileC ) ) ); - $this->create( array( 'dst' => $fileC, 'content' => $fileCContents ) ); - - $status = $this->backend->doOperations( array( - array( 'op' => 'copy', 'src' => $fileA, 'dst' => $fileC, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: (file:) - array( 'op' => 'copy', 'src' => $fileC, 'dst' => $fileA, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'copy', 'src' => $fileB, 'dst' => $fileD, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'move', 'src' => $fileC, 'dst' => $fileD ), - // Now: A:, B:, C:, D: (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileC, 'overwriteSame' => 1 ), - // Now: A:, B:, C:, D: (failed) - array( 'op' => 'move', 'src' => $fileB, 'dst' => $fileA, 'overwrite' => 1 ), - // Now: A:, B:, C:, D: - array( 'op' => 'delete', 'src' => $fileD ), - // Now: A:, B:, C:, D: - array( 'op' => 'null' ), - // Does nothing - ), array( 'force' => 1 ) ); - - $this->assertNotEquals( array(), $status->errors, "Operation had warnings" ); - $this->assertEquals( true, $status->isOK(), "Operation batch succeeded" ); - $this->assertEquals( 8, count( $status->success ), - "Operation batch has correct success array" ); - - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileB ) ), - "File does not exist at $fileB" ); - $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $fileD ) ), - "File does not exist at $fileD" ); - - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileA ) ), - "File does not exist at $fileA" ); - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $fileC ) ), - "File exists at $fileC" ); - $this->assertEquals( $fileBContents, - $this->backend->getFileContents( array( 'src' => $fileA ) ), - "Correct file contents of $fileA" ); - $this->assertEquals( strlen( $fileBContents ), - $this->backend->getFileSize( array( 'src' => $fileA ) ), - "Correct file size of $fileA" ); - $this->assertEquals( wfBaseConvert( sha1( $fileBContents ), 16, 36, 31 ), - $this->backend->getFileSha1Base36( array( 'src' => $fileA ) ), - "Correct file SHA-1 of $fileA" ); - } - - public function testGetFileList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetFileList(); - $this->tearDownFiles(); - } - - private function doTestGetFileList() { - $backendName = $this->backendClass(); - $base = $this->baseStorePath(); - - // Should have no errors - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont-notexists" ) ); - - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir2/subdir/test2.txt", - "$base/unittest-cont1/e/subdir2/subdir/test3.txt", - "$base/unittest-cont1/e/subdir2/subdir/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test5.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir2/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - // Expected listing - $expected = array( - "e/test1.txt", - "e/test2.txt", - "e/test3.txt", - "e/subdir1/test1.txt", - "e/subdir1/test2.txt", - "e/subdir2/test3.txt", - "e/subdir2/test4.txt", - "e/subdir2/subdir/test1.txt", - "e/subdir2/subdir/test2.txt", - "e/subdir2/subdir/test3.txt", - "e/subdir2/subdir/test4.txt", - "e/subdir2/subdir/test5.txt", - "e/subdir2/subdir/sub/test0.txt", - "e/subdir2/subdir/sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - - // Expected listing - $expected = array( - "test1.txt", - "test2.txt", - "test3.txt", - "test4.txt", - "test5.txt", - "sub/test0.txt", - "sub/120-px-file.txt", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." ); - - // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct file listing ($backendName), second iteration." ); - - // Expected listing (top files only) - $expected = array( - "test1.txt", - "test2.txt", - "test3.txt", - "test4.txt", - "test5.txt" - ); - sort( $expected ); - - // Actual listing (top files only) - $list = array(); - $iter = $this->backend->getTopFileList( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top file listing ($backendName)." ); - - foreach ( $files as $file ) { // clean up - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getFileList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) {} // no errors - } - - public function testGetDirectoryList() { - $this->backend = $this->singleBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - - $this->backend = $this->multiBackend; - $this->tearDownFiles(); - $this->doTestGetDirectoryList(); - $this->tearDownFiles(); - } - - private function doTestGetDirectoryList() { - $backendName = $this->backendClass(); - - $base = $this->baseStorePath(); - $files = array( - "$base/unittest-cont1/e/test1.txt", - "$base/unittest-cont1/e/test2.txt", - "$base/unittest-cont1/e/test3.txt", - "$base/unittest-cont1/e/subdir1/test1.txt", - "$base/unittest-cont1/e/subdir1/test2.txt", - "$base/unittest-cont1/e/subdir2/test3.txt", - "$base/unittest-cont1/e/subdir2/test4.txt", - "$base/unittest-cont1/e/subdir2/subdir/test1.txt", - "$base/unittest-cont1/e/subdir3/subdir/test2.txt", - "$base/unittest-cont1/e/subdir4/subdir/test3.txt", - "$base/unittest-cont1/e/subdir4/subdir/test4.txt", - "$base/unittest-cont1/e/subdir4/subdir/test5.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/test0.txt", - "$base/unittest-cont1/e/subdir4/subdir/sub/120-px-file.txt", - ); - - // Add the files - $ops = array(); - foreach ( $files as $file ) { - $this->prepare( array( 'dir' => dirname( $file ) ) ); - $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file ); - } - $status = $this->backend->doQuickOperations( $ops ); - $this->assertGoodStatus( $status, - "Creation of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Creation of files succeeded with OK status ($backendName)." ); - - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir1" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( true, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/subdir" ) ), - "Directory exists in ($backendName)." ); - $this->assertEquals( false, - $this->backend->directoryExists( array( 'dir' => "$base/unittest-cont1/e/subdir2/test1.txt" ) ), - "Directory does not exists in ($backendName)." ); - - // Expected listing - $expected = array( - "e", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir1", - "subdir2", - "subdir3", - "subdir4", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Expected listing - $expected = array( - "subdir", - ); - sort( $expected ); - - // Actual listing (no trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (with trailing slash) - $list = array(); - $iter = $this->backend->getTopDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir2/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName)." ); - - // Actual listing (using iterator second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct top dir listing ($backendName), second iteration." ); - - // Expected listing (recursive) - $expected = array( - "e", - "e/subdir1", - "e/subdir2", - "e/subdir3", - "e/subdir4", - "e/subdir2/subdir", - "e/subdir3/subdir", - "e/subdir4/subdir", - "e/subdir4/subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Expected listing (recursive) - $expected = array( - "subdir", - "subdir/sub", - ); - sort( $expected ); - - // Actual listing (recursive) - $list = array(); - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/e/subdir4" ) ); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - // Actual listing (recursive, second time) - $list = array(); - foreach ( $iter as $file ) { - $list[] = $file; - } - sort( $list ); - - $this->assertEquals( $expected, $list, "Correct dir listing ($backendName)." ); - - foreach ( $files as $file ) { // clean up - $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) ); - } - - $iter = $this->backend->getDirectoryList( array( 'dir' => "$base/unittest-cont1/not/exists" ) ); - foreach ( $iter as $iter ) {} // no errors - } - - public function testLockCalls() { - $this->backend = $this->singleBackend; - $this->doTestLockCalls(); - } - - private function doTestLockCalls() { - $backendName = $this->backendClass(); - - for ( $i=0; $i<50; $i++ ) { - $paths = array( - "test1.txt", - "test2.txt", - "test3.txt", - "subdir1", - "subdir1", // duplicate - "subdir1/test1.txt", - "subdir1/test2.txt", - "subdir2", - "subdir2", // duplicate - "subdir2/test3.txt", - "subdir2/test4.txt", - "subdir2/subdir", - "subdir2/subdir/test1.txt", - "subdir2/subdir/test2.txt", - "subdir2/subdir/test3.txt", - "subdir2/subdir/test4.txt", - "subdir2/subdir/test5.txt", - "subdir2/subdir/sub", - "subdir2/subdir/sub/test0.txt", - "subdir2/subdir/sub/120-px-file.txt", - ); - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( array(), $status->errors, - "Locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName)." ); - - $status = $this->backend->lockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( array(), $status->errors, - "Locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_SH ); - $this->assertEquals( array(), $status->errors, - "Locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName)." ); - - $status = $this->backend->unlockFiles( $paths, LockManager::LOCK_EX ); - $this->assertEquals( array(), $status->errors, - "Locking of files succeeded ($backendName)." ); - $this->assertEquals( true, $status->isOK(), - "Locking of files succeeded with OK status ($backendName)." ); - } - } - - // test helper wrapper for backend prepare() function - private function prepare( array $params ) { - return $this->backend->prepare( $params ); - } - - // test helper wrapper for backend prepare() function - private function create( array $params ) { - $params['op'] = 'create'; - return $this->backend->doQuickOperations( array( $params ) ); - } - - function tearDownFiles() { - foreach ( $this->filesToPrune as $file ) { - @unlink( $file ); - } - $containers = array( 'unittest-cont1', 'unittest-cont2', 'unittest-cont3' ); - foreach ( $containers as $container ) { - $this->deleteFiles( $container ); - } - $this->filesToPrune = array(); - } - - private function deleteFiles( $container ) { - $base = $this->baseStorePath(); - $iter = $this->backend->getFileList( array( 'dir' => "$base/$container" ) ); - if ( $iter ) { - foreach ( $iter as $file ) { - $this->backend->delete( array( 'src' => "$base/$container/$file" ), - array( 'force' => 1, 'nonLocking' => 1 ) ); - } - } - $this->backend->clean( array( 'dir' => "$base/$container", 'recursive' => 1 ) ); - } - - function assertBackendPathsConsistent( array $paths ) { - if ( $this->backend instanceof FileBackendMultiWrite ) { - $status = $this->backend->consistencyCheck( $paths ); - $this->assertGoodStatus( $status, "Files synced: " . implode( ',', $paths ) ); - } - } - - function assertGoodStatus( $status, $msg ) { - $this->assertEquals( print_r( array(), 1 ), print_r( $status->errors, 1 ), $msg ); - } - - function tearDown() { - parent::tearDown(); - } -} diff --git a/tests/phpunit/includes/filerepo/FileRepoTest.php b/tests/phpunit/includes/filerepo/FileRepoTest.php deleted file mode 100644 index 8f92c123..00000000 --- a/tests/phpunit/includes/filerepo/FileRepoTest.php +++ /dev/null @@ -1,45 +0,0 @@ - 'foobar' - ) ); - } - /** - * @expectedException MWException - */ - function testFileRepoConstructionOptionNeedBackendKey() { - $f = new FileRepo( array( - 'name' => 'foobar' - ) ); - } - - function testFileRepoConstructionWithRequiredOptions() { - $f = new FileRepo( array( - 'name' => 'FileRepoTestRepository', - 'backend' => new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array() - ) ) - ) ); - $this->assertInstanceOf( 'FileRepo', $f ); - } -} diff --git a/tests/phpunit/includes/filerepo/StoreBatchTest.php b/tests/phpunit/includes/filerepo/StoreBatchTest.php deleted file mode 100644 index 3ab56af8..00000000 --- a/tests/phpunit/includes/filerepo/StoreBatchTest.php +++ /dev/null @@ -1,123 +0,0 @@ -getCliArg( 'use-filebackend=' ) ) { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-testing'; // swap name - $class = $useConfig['class']; - $backend = new $class( $useConfig ); - } else { - $backend = new FSFileBackend( array( - 'name' => 'local-testing', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'unittests-public' => "{$tmpPrefix}-public", - 'unittests-thumb' => "{$tmpPrefix}-thumb", - 'unittests-temp' => "{$tmpPrefix}-temp", - 'unittests-deleted' => "{$tmpPrefix}-deleted", - ) - ) ); - } - $this->repo = new FileRepo( array( - 'name' => 'unittests', - 'backend' => $backend - ) ); - - $this->date = gmdate( "YmdHis" ); - $this->createdFiles = array(); - } - - /** - * Store a file or virtual URL source into a media file name. - * - * @param $originalName string The title of the image - * @param $srcPath string The filepath or virtual URL - * @param $flags integer Flags to pass into repo::store(). - */ - private function storeit($originalName, $srcPath, $flags) { - $hashPath = $this->repo->getHashPath( $originalName ); - $dstRel = "$hashPath{$this->date}!$originalName"; - $dstUrlRel = $hashPath . $this->date . '!' . rawurlencode( $originalName ); - - $result = $this->repo->store( $srcPath, 'temp', $dstRel, $flags ); - $result->value = $this->repo->getVirtualUrl( 'temp' ) . '/' . $dstUrlRel; - $this->createdFiles[] = $result->value; - return $result; - } - - /** - * Test storing a file using different flags. - * - * @param $fn string The title of the image - * @param $infn string The name of the file (in the filesystem) - * @param $otherfn string The name of the different file (in the filesystem) - * @param $fromrepo logical 'true' if we want to copy from a virtual URL out of the Repo. - */ - private function storecohort($fn, $infn, $otherfn, $fromrepo) { - $f = $this->storeit( $fn, $infn, 0 ); - $this->assertTrue( $f->isOK(), 'failed to store a new file' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" ); - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $infn, FileRepo::OVERWRITE); - $infn = $f->value; - } - // This should work because we're allowed to overwrite - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE ); - $this->assertTrue( $f->isOK(), 'We should be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting. - $f = $this->storeit( $fn, $infn, 0 ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 0 , "counts wrong {$f->successCount} {$f->failCount}" ); - // This should succeed because we're overwriting the same content. - $f = $this->storeit( $fn, $infn, FileRepo::OVERWRITE_SAME ); - $this->assertTrue( $f->isOK(), 'We should be able to overwrite the same content' ); - $this->assertEquals( $f->failCount, 0, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 1 , "counts wrong {$f->successCount} {$f->failCount}" ); - // This should fail because we're overwriting different content. - if ( $fromrepo ) { - $f = $this->storeit( "Other-$fn", $otherfn, FileRepo::OVERWRITE); - $otherfn = $f->value; - } - $f = $this->storeit( $fn, $otherfn, FileRepo::OVERWRITE_SAME ); - $this->assertFalse( $f->isOK(), 'We should not be allowed to overwrite different content' ); - $this->assertEquals( $f->failCount, 1, "counts wrong {$f->successCount} {$f->failCount}" ); - $this->assertEquals( $f->successCount, 0 , "counts wrong {$f->successCount} {$f->failCount}" ); - } - - public function teststore() { - global $IP; - $this->storecohort( "Test1.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", false ); - $this->storecohort( "Test2.png", "$IP/skins/monobook/wiki.png", "$IP/skins/monobook/video.png", true ); - } - - public function tearDown() { - $this->repo->cleanupBatch( $this->createdFiles ); // delete files - foreach ( $this->createdFiles as $tmp ) { // delete dirs - $tmp = $this->repo->resolveVirtualUrl( $tmp ); - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - $this->repo->getBackend()->clean( array( 'dir' => $tmp ) ); - } - } - parent::tearDown(); - } -} diff --git a/tests/phpunit/includes/installer/InstallDocFormatterTest.php b/tests/phpunit/includes/installer/InstallDocFormatterTest.php deleted file mode 100644 index 56485d3e..00000000 --- a/tests/phpunit/includes/installer/InstallDocFormatterTest.php +++ /dev/null @@ -1,64 +0,0 @@ -assertEquals( - $expected, - InstallDocFormatter::format( $unformattedText ), - $message - ); - } - - /** - * Provider for testFormat() - */ - function provideDocFormattingTests() { - # Format: (expected string, unformattedText string, optional message) - return array( - # Escape some wikitext - array( 'Install <tag>' , 'Install ', 'Escaping <' ), - array( 'Install {{template}}' , 'Install {{template}}', 'Escaping [[' ), - array( 'Install [[page]]' , 'Install [[page]]', 'Escaping {{' ), - array( 'Install ' , "Install \r", 'Removing \r' ), - - # Transform \t{1,2} into :{1,2} - array( ':One indentation', "\tOne indentation", 'Replacing a single \t' ), - array( '::Two indentations', "\t\tTwo indentations", 'Replacing 2 x \t' ), - - # Transform 'bug 123' links - array( - '[https://bugzilla.wikimedia.org/123 bug 123]', - 'bug 123', 'Testing bug 123 links' ), - array( - '([https://bugzilla.wikimedia.org/987654 bug 987654])', - '(bug 987654)', 'Testing (bug 987654) links' ), - - # "bug abc" shouldn't work - array( 'bug foobar', 'bug foobar', "Don't match bug followed by non-digits" ), - array( 'bug !!fakefake!!', 'bug !!fakefake!!', "Don't match bug followed by non-digits" ), - - # Transform '$wgFooBar' links - array( - '[http://www.mediawiki.org/wiki/Manual:$wgFooBar $wgFooBar]', - '$wgFooBar', 'Testing basic $wgFooBar' ), - array( - '[http://www.mediawiki.org/wiki/Manual:$wgFooBar45 $wgFooBar45]', - '$wgFooBar45', 'Testing $wgFooBar45 (with numbers)' ), - array( - '[http://www.mediawiki.org/wiki/Manual:$wgFoo_Bar $wgFoo_Bar]', - '$wgFoo_Bar', 'Testing $wgFoo_Bar (with underscore)' ), - - # Icky variables that shouldn't link - array( '$myAwesomeVariable', '$myAwesomeVariable', 'Testing $myAwesomeVariable (not starting with $wg)' ), - array( '$()not!a&Var', '$()not!a&Var', 'Testing $()not!a&Var (obviously not a variable)' ), - ); - } -} diff --git a/tests/phpunit/includes/json/ServicesJsonTest.php b/tests/phpunit/includes/json/ServicesJsonTest.php deleted file mode 100644 index 8f2421a2..00000000 --- a/tests/phpunit/includes/json/ServicesJsonTest.php +++ /dev/null @@ -1,93 +0,0 @@ -encode() - * produce the same output - * - * @dataProvider provideValuesToEncode - */ - public function testJsonEncode( $input, $desc ) { - if ( !function_exists( 'json_encode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } elseif( strtolower( json_encode( "\xf0\xa0\x80\x80" ) ) != '"\ud840\udc00"' ) { - $this->markTestIncomplete( 'Have buggy PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->encode( $input ), - json_encode( $input ), - $desc - ); - } - } - - /** - * Test to make sure core json_decode() and our Services_Json()->decode() - * produce the same output - * - * @dataProvider provideValuesToDecode - */ - public function testJsonDecode( $input, $desc ) { - if ( !function_exists( 'json_decode' ) ) { - $this->markTestIncomplete( 'No PHP json support, unable to test' ); - return; - } else { - $jsonObj = new Services_JSON(); - $this->assertEquals( - $jsonObj->decode( $input ), - json_decode( $input ), - $desc - ); - } - } - - function provideValuesToEncode() { - $obj = new stdClass(); - $obj->property = 'value'; - $obj->property2 = null; - $obj->property3 = 1.234; - return array( - array( 1, 'basic integer' ), - array( -1, 'negative integer' ), - array( 1.1, 'basic float' ), - array( true, 'basic bool true' ), - array( false, 'basic bool false' ), - array( 'some string', 'basic string test' ), - array( "some string\nwith newline", 'newline string test' ), - array( '♥ü', 'unicode string test' ), - array( array( 'some', 'string', 'values' ), 'basic array of strings' ), - array( array( 'key1' => 'val1', 'key2' => 'val2' ), 'array with string keys' ), - array( array( 1 => 'val1', 3 => 'val2', '2' => 'val3' ), 'out of order numbered array test' ), - array( array(), 'empty array test' ), - array( $obj, 'basic object test' ), - array( new stdClass, 'empty object test' ), - array( null, 'null test' ), - ); - } - - function provideValuesToDecode() { - return array( - array( '1', 'basic integer' ), - array( '-1', 'negative integer' ), - array( '1.1', 'basic float' ), - array( '1.1e1', 'scientific float' ), - array( 'true', 'basic bool true' ), - array( 'false', 'basic bool false' ), - array( '"some string"', 'basic string test' ), - array( '"some string\nwith newline"', 'newline string test' ), - array( '"♥ü"', 'unicode character string test' ), - array( '"\u2665"', 'unicode \\u string test' ), - array( '["some","string","values"]', 'basic array of strings' ), - array( '[]', 'empty array test' ), - array( '{"key":"value"}', 'Basic key => value test' ), - array( '{}', 'empty object test' ), - array( 'null', 'null test' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSJanusTest.php b/tests/phpunit/includes/libs/CSSJanusTest.php deleted file mode 100644 index 54f66077..00000000 --- a/tests/phpunit/includes/libs/CSSJanusTest.php +++ /dev/null @@ -1,560 +0,0 @@ -assertEquals( $transformedA, $cssB, 'Test A-B transformation' ); - - $transformedB = CSSJanus::transform( $cssB ); - $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' ); - - // If no B version is provided, it means - // the output should equal the input. - } else { - $transformedA = CSSJanus::transform( $cssA ); - $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' ); - } - } - - /** - * @dataProvider provideTransformAdvancedCases - */ - function testTransformAdvanced( $code, $expectedOutput, $options = array() ) { - $swapLtrRtlInURL = isset( $options['swapLtrRtlInURL'] ) ? $options['swapLtrRtlInURL'] : false; - $swapLeftRightInURL = isset( $options['swapLeftRightInURL'] ) ? $options['swapLeftRightInURL'] : false; - - $flipped = CSSJanus::transform( $code, $swapLtrRtlInURL, $swapLeftRightInURL ); - - $this->assertEquals( $expectedOutput, $flipped, - 'Test flipping, options: url-ltr-rtl=' . ($swapLtrRtlInURL ? 'true' : 'false') - . ' url-left-right=' . ($swapLeftRightInURL ? 'true' : 'false') - ); - } - /** - * @dataProvider provideTransformBrokenCases - * @group Broken - */ - function testTransformBroken( $code, $expectedOutput ) { - $flipped = CSSJanus::transform( $code ); - - $this->assertEquals( $expectedOutput, $flipped, 'Test flipping' ); - } - - /** - * These transform cases are tested *in both directions* - * No need to declare a principle twice in both directions here. - */ - function provideTransformCases() { - return array( - // Property keys - array( - '.foo { left: 0; }', - '.foo { right: 0; }' - ), - // Guard against partial keys - // (CSS currently doesn't have flippable properties - // that contain the direction as part of the key without - // dash separation) - array( - '.foo { alright: 0; }' - ), - array( - '.foo { balleft: 0; }' - ), - - // Dashed property keys - array( - '.foo { padding-left: 0; }', - '.foo { padding-right: 0; }' - ), - array( - '.foo { margin-left: 0; }', - '.foo { margin-right: 0; }' - ), - array( - '.foo { border-left: 0; }', - '.foo { border-right: 0; }' - ), - - // Double-dashed property keys - array( - '.foo { border-left-color: red; }', - '.foo { border-right-color: red; }' - ), - array( - // Includes unknown properties? - '.foo { x-left-y: 0; }', - '.foo { x-right-y: 0; }' - ), - - // Multi-value properties - array( - '.foo { padding: 0; }' - ), - array( - '.foo { padding: 0 1px; }' - ), - array( - '.foo { padding: 0 1px 2px; }' - ), - array( - '.foo { padding: 0 1px 2px 3px; }', - '.foo { padding: 0 3px 2px 1px; }' - ), - - // Shorthand / Four notation - array( - '.foo { padding: .25em 15px 0pt 0ex; }', - '.foo { padding: .25em 0ex 0pt 15px; }' - ), - array( - '.foo { margin: 1px -4px 3px 2px; }', - '.foo { margin: 1px 2px 3px -4px; }' - ), - array( - '.foo { padding: 0 15px .25em 0; }', - '.foo { padding: 0 0 .25em 15px; }' - ), - array( - '.foo { padding: 1px 4.1grad 3px 2%; }', - '.foo { padding: 1px 2% 3px 4.1grad; }' - ), - array( - '.foo { padding: 1px 2px 3px auto; }', - '.foo { padding: 1px auto 3px 2px; }' - ), - array( - '.foo { padding: 1px inherit 3px auto; }', - '.foo { padding: 1px auto 3px inherit; }' - ), - array( - '.foo { border-radius: .25em 15px 0pt 0ex; }', - '.foo { border-radius: .25em 0ex 0pt 15px; }' - ), - array( - '.foo { x-unknown: a b c d; }' - ), - array( - '.foo barpx 0 2% { opacity: 0; }' - ), - array( - '#settings td p strong' - ), - array( - # Not sure how 4+ values should behave, - # testing to make sure changes are detected - '.foo { x-unknown: 1 2 3 4 5; }', - '.foo { x-unknown: 1 4 3 2 5; }', - ), - array( - '.foo { x-unknown: 1 2 3 4 5 6; }', - '.foo { x-unknown: 1 4 3 2 5 6; }', - ), - - // Shorthand / Three notation - array( - '.foo { margin: 1em 0 .25em; }' - ), - array( - '.foo { margin:-1.5em 0 -.75em; }' - ), - - // Shorthand / Two notation - array( - '.foo { padding: 1px 2px; }' - ), - - // Shorthand / One notation - array( - '.foo { padding: 1px; }' - ), - - // Direction - // Note: This differs from the Python implementation, - // see also CSSJanus::fixDirection for more info. - array( - '.foo { direction: ltr; }', - '.foo { direction: rtl; }' - ), - array( - '.foo { direction: rtl; }', - '.foo { direction: ltr; }' - ), - array( - 'input { direction: ltr; }', - 'input { direction: rtl; }' - ), - array( - 'input { direction: rtl; }', - 'input { direction: ltr; }' - ), - array( - 'body { direction: ltr; }', - 'body { direction: rtl; }' - ), - array( - '.foo, body, input { direction: ltr; }', - '.foo, body, input { direction: rtl; }' - ), - array( - 'body { padding: 10px; direction: ltr; }', - 'body { padding: 10px; direction: rtl; }' - ), - array( - 'body { direction: ltr } .myClass { direction: ltr }', - 'body { direction: rtl } .myClass { direction: rtl }' - ), - - // Left/right values - array( - '.foo { float: left; }', - '.foo { float: right; }' - ), - array( - '.foo { text-align: left; }', - '.foo { text-align: right; }' - ), - array( - '.foo { -x-unknown: left; }', - '.foo { -x-unknown: right; }' - ), - // Guard against selectors that look flippable - array( - '.column-left { width: 0; }' - ), - array( - 'a.left { width: 0; }' - ), - array( - 'a.leftification { width: 0; }' - ), - array( - 'a.ltr { width: 0; }' - ), - array( - #
    - '.a-ltr.png { width: 0; }' - ), - array( - # - 'foo-ltr[attr="x"] { width: 0; }' - ), - array( - 'div.left > span.right+span.left { width: 0; }' - ), - array( - '.thisclass .left .myclass { width: 0; }' - ), - array( - '.thisclass .left .myclass #myid { width: 0; }' - ), - - // Cursor values (east/west) - array( - '.foo { cursor: e-resize; }', - '.foo { cursor: w-resize; }' - ), - array( - '.foo { cursor: se-resize; }', - '.foo { cursor: sw-resize; }' - ), - array( - '.foo { cursor: ne-resize; }', - '.foo { cursor: nw-resize; }' - ), - - // Background - array( - '.foo { background-position: top left; }', - '.foo { background-position: top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left; }', - '.foo { background: url(/foo/bar.png) top right; }' - ), - array( - '.foo { background: url(/foo/bar.png) top left no-repeat; }', - '.foo { background: url(/foo/bar.png) top right no-repeat; }' - ), - array( - '.foo { background: url(/foo/bar.png) no-repeat top left; }', - '.foo { background: url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background: #fff url(/foo/bar.png) no-repeat top left; }', - '.foo { background: #fff url(/foo/bar.png) no-repeat top right; }' - ), - array( - '.foo { background-position: 100% 40%; }', - '.foo { background-position: 0% 40%; }' - ), - array( - '.foo { background-position: 23% 0; }', - '.foo { background-position: 77% 0; }' - ), - array( - '.foo { background-position: 23% auto; }', - '.foo { background-position: 77% auto; }' - ), - array( - '.foo { background-position-x: 23%; }', - '.foo { background-position-x: 77%; }' - ), - array( - '.foo { background-position-y: 23%; }', - '.foo { background-position-y: 23%; }' - ), - array( - '.foo { background:url(../foo.png) no-repeat 75% 50%; }', - '.foo { background:url(../foo.png) no-repeat 25% 50%; }' - ), - array( - '.foo { background: 10% 20% } .bar { background: 40% 30% }', - '.foo { background: 90% 20% } .bar { background: 60% 30% }' - ), - - // Multiple rules - array( - 'body { direction: rtl; float: right; } .foo { direction: ltr; float: right; }', - 'body { direction: ltr; float: left; } .foo { direction: rtl; float: left; }', - ), - - // Duplicate properties - array( - '.foo { float: left; float: right; float: left; }', - '.foo { float: right; float: left; float: right; }', - ), - - // Preserve comments - array( - '/* left /* right */left: 10px', - '/* left /* right */right: 10px' - ), - array( - '/*left*//*left*/left: 10px', - '/*left*//*left*/right: 10px' - ), - array( - '/* Going right is cool */ .foo { width: 0 }', - ), - array( - "/* padding-right 1 2 3 4 */\n#test { width: 0}\n/*right*/" - ), - array( - "/** Two line comment\n * left\n \*/\n#test {width: 0}" - ), - - // @noflip annotation - array( - // before selector (single) - '/* @noflip */ div { float: left; }' - ), - array( - // before selector (multiple) - '/* @noflip */ div, .notme { float: left; }' - ), - array( - // inside selector - 'div, /* @noflip */ .foo { float: left; }' - ), - array( - // after selector - 'div, .notme /* @noflip */ { float: left; }' - ), - array( - // before multiple rules - '/* @noflip */ div { float: left; } .foo { float: left; }', - '/* @noflip */ div { float: left; } .foo { float: right; }' - ), - array( - // after multiple rules - '.foo { float: left; } /* @noflip */ div { float: left; }', - '.foo { float: right; } /* @noflip */ div { float: left; }' - ), - array( - // before multiple properties - 'div { /* @noflip */ float: left; text-align: left; }', - 'div { /* @noflip */ float: left; text-align: right; }' - ), - array( - // after multiple properties - 'div { float: left; /* @noflip */ text-align: left; }', - 'div { float: right; /* @noflip */ text-align: left; }' - ), - - // Guard against css3 stuff - array( - 'background-image: -moz-linear-gradient(#326cc1, #234e8c);' - ), - array( - 'background-image: -webkit-gradient(linear, 100% 0%, 0% 0%, from(#666666), to(#ffffff));' - ), - - // CSS syntax / white-space variations - // spaces, no spaces, tabs, new lines, omitting semi-colons - array( - ".foo { left: 0; }", - ".foo { right: 0; }" - ), - array( - ".foo{ left: 0; }", - ".foo{ right: 0; }" - ), - array( - ".foo{ left: 0 }", - ".foo{ right: 0 }" - ), - array( - ".foo{left:0 }", - ".foo{right:0 }" - ), - array( - ".foo{left:0}", - ".foo{right:0}" - ), - array( - ".foo { left : 0 ; }", - ".foo { right : 0 ; }" - ), - array( - ".foo\n { left : 0 ; }", - ".foo\n { right : 0 ; }" - ), - array( - ".foo\n { \nleft : 0 ; }", - ".foo\n { \nright : 0 ; }" - ), - array( - ".foo\n { \n left : 0 ; }", - ".foo\n { \n right : 0 ; }" - ), - array( - ".foo\n { \n left\n : 0; }", - ".foo\n { \n right\n : 0; }" - ), - array( - ".foo \n { \n left\n : 0; }", - ".foo \n { \n right\n : 0; }" - ), - array( - ".foo\n{\nleft\n:\n0;}", - ".foo\n{\nright\n:\n0;}" - ), - array( - ".foo\n.bar {\n\tleft: 0;\n}", - ".foo\n.bar {\n\tright: 0;\n}" - ), - array( - ".foo\t{\tleft\t:\t0;}", - ".foo\t{\tright\t:\t0;}" - ), - ); - } - - /** - * These cases are tested in one way only (format: actual, expected, msg). - * If both ways can be tested, either put both versions in here or move - * it to provideTransformCases(). - */ - function provideTransformAdvancedCases() { - $bgPairs = array( - # [ - _ . ] <-> [ left right ltr rtl ] - 'foo.jpg' => 'foo.jpg', - 'left.jpg' => 'right.jpg', - 'ltr.jpg' => 'rtl.jpg', - - 'foo-left.png' => 'foo-right.png', - 'foo_left.png' => 'foo_right.png', - 'foo.left.png' => 'foo.right.png', - - 'foo-ltr.png' => 'foo-rtl.png', - 'foo_ltr.png' => 'foo_rtl.png', - 'foo.ltr.png' => 'foo.rtl.png', - - 'left-foo.png' => 'right-foo.png', - 'left_foo.png' => 'right_foo.png', - 'left.foo.png' => 'right.foo.png', - - 'ltr-foo.png' => 'rtl-foo.png', - 'ltr_foo.png' => 'rtl_foo.png', - 'ltr.foo.png' => 'rtl.foo.png', - - 'foo-ltr-left.gif' => 'foo-rtl-right.gif', - 'foo_ltr_left.gif' => 'foo_rtl_right.gif', - 'foo.ltr.left.gif' => 'foo.rtl.right.gif', - 'foo-ltr_left.gif' => 'foo-rtl_right.gif', - 'foo_ltr.left.gif' => 'foo_rtl.right.gif', - ); - $provider = array(); - foreach ( $bgPairs as $left => $right ) { - # By default '-rtl' and '-left' etc. are not touched, - # Only when the appropiate parameter is set. - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$left); }" - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$right); }" - ); - $provider[] = array( - ".foo { background: url(images/$left); }", - ".foo { background: url(images/$right); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - $provider[] = array( - ".foo { background: url(images/$right); }", - ".foo { background: url(images/$left); }", - array( - 'swapLtrRtlInURL' => true, - 'swapLeftRightInURL' => true, - ) - ); - } - - return $provider; - } - - /** - * Cases that are currently failing, but - * should be looked at in the future as enhancements and/or bug fix - */ - function provideTransformBrokenCases() { - return array( - // Guard against partial keys - array( - '.foo { leftxx: 0; }', - '.foo { leftxx: 0; }' - ), - array( - '.foo { rightxx: 0; }', - '.foo { rightxx: 0; }' - ), - - // Guard against selectors that look flippable - array( - # - 'foo-left-x[attr="x"] { width: 0; }', - 'foo-left-x[attr="x"] { width: 0; }' - ), - array( - #
    - '.foo[data-left="x"] { width: 0; }', - '.foo[data-left="x"] { width: 0; }' - ), - ); - } -} diff --git a/tests/phpunit/includes/libs/CSSMinTest.php b/tests/phpunit/includes/libs/CSSMinTest.php deleted file mode 100644 index a3827756..00000000 --- a/tests/phpunit/includes/libs/CSSMinTest.php +++ /dev/null @@ -1,142 +0,0 @@ -oldServer = $wgServer; - $this->oldCanServer = $wgCanonicalServer; - $wgServer = $wgCanonicalServer = 'http://wiki.example.org'; - } - - function tearDown() { - // Restore $wgServer and $wgCanonicalServer - global $wgServer, $wgCanonicalServer; - $wgServer = $this->oldServer; - $wgCanonicalServer = $this->oldCanServer; - - parent::tearDown(); - } - - /** - * @dataProvider provideMinifyCases - */ - function testMinify( $code, $expectedOutput ) { - $minified = CSSMin::minify( $code ); - - $this->assertEquals( $expectedOutput, $minified, 'Minified output should be in the form expected.' ); - } - - function provideMinifyCases() { - return array( - // Whitespace - array( "\r\t\f \v\n\r", "" ), - array( "foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - - // Loose comments - array( "/* foo */", "" ), - array( "/*******\n foo\n *******/", "" ), - array( "/*!\n foo\n */", "" ), - - // Inline comments in various different places - array( "/* comment */foo, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo/* comment */, bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo,/* comment */ bar {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar/* comment */ {\n\tprop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\t/* comment */prop: value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: /* comment */value;\n}", "foo,bar{prop:value}" ), - array( "foo, bar {\n\tprop: value /* comment */;\n}", "foo,bar{prop:value }" ), - array( "foo, bar {\n\tprop: value; /* comment */\n}", "foo,bar{prop:value; }" ), - - // Keep track of things that aren't as minified as much as they - // could be (bug 35493) - array( 'foo { prop: value ;}', 'foo{prop:value }' ), - array( 'foo { prop : value; }', 'foo{prop :value}' ), - array( 'foo { prop: value ; }', 'foo{prop:value }' ), - array( 'foo { font-family: "foo" , "bar"; }', 'foo{font-family:"foo" ,"bar"}' ), - array( "foo { src:\n\turl('foo') ,\n\turl('bar') ; }", "foo{src:url('foo') ,url('bar') }" ), - - // Interesting cases with string values - // - Double quotes, single quotes - array( 'foo { content: ""; }', 'foo{content:""}' ), - array( "foo { content: ''; }", "foo{content:''}" ), - array( 'foo { content: "\'"; }', 'foo{content:"\'"}' ), - array( "foo { content: '\"'; }", "foo{content:'\"'}" ), - // - Whitespace in string values - array( 'foo { content: " "; }', 'foo{content:" "}' ), - ); - } - - /** - * @dataProvider provideRemapCases - */ - function testRemap( $message, $params, $expectedOutput ) { - $remapped = call_user_func_array( 'CSSMin::remap', $params ); - - $messageAdd = " Case: $message"; - $this->assertEquals( $expectedOutput, $remapped, 'CSSMin::remap should return the expected url form.' . $messageAdd ); - } - - function provideRemapCases() { - // Parameter signature: - // CSSMin::remap( $code, $local, $remote, $embedData = true ) - return array( - array( - 'Simple case', - array( 'foo { prop: url(bar.png); }', false, 'http://example.org', false ), - 'foo { prop: url(http://example.org/bar.png); }', - ), - array( - 'Without trailing slash', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'With trailing slash on remote (bug 27052)', - array( 'foo { prop: url(../bar.png); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/../bar.png); }', - ), - array( - 'Guard against stripping double slashes from query', - array( 'foo { prop: url(bar.png?corge=//grault); }', false, 'http://example.org/quux/', false ), - 'foo { prop: url(http://example.org/quux/bar.png?corge=//grault); }', - ), - array( - 'Expand absolute paths', - array( 'foo { prop: url(/w/skin/images/bar.png); }', false, 'http://example.org/quux', false ), - 'foo { prop: url(http://wiki.example.org/w/skin/images/bar.png); }', - ), - ); - } - - /** - * Seperated because they are currently broken (bug 35492) - * - * @group Broken - * @dataProvider provideStringCases - */ - function testMinifyWithCSSStringValues( $code, $expectedOutput ) { - $this->testMinifyOutput( $code, $expectedOutput ); - } - - function provideStringCases() { - return array( - // String values should be respected - // - More than one space in a string value - array( 'foo { content: " "; }', 'foo{content:" "}' ), - // - Using a tab in a string value (turns into a space) - array( "foo { content: '\t'; }", "foo{content:'\t'}" ), - // - Using css-like syntax in string values - array( 'foo::after { content: "{;}"; position: absolute; }', 'foo::after{content:"{;}";position:absolute}' ), - ); - } -} diff --git a/tests/phpunit/includes/libs/GenericArrayObjectTest.php b/tests/phpunit/includes/libs/GenericArrayObjectTest.php deleted file mode 100644 index 70fce111..00000000 --- a/tests/phpunit/includes/libs/GenericArrayObjectTest.php +++ /dev/null @@ -1,245 +0,0 @@ - - */ -abstract class GenericArrayObjectTest extends MediaWikiTestCase { - - /** - * Returns objects that can serve as elements in the concrete GenericArrayObject deriving class being tested. - * - * @since 1.20 - * - * @return array - */ - public abstract function elementInstancesProvider(); - - /** - * Returns the name of the concrete class being tested. - * - * @since 1.20 - * - * @return string - */ - public abstract function getInstanceClass(); - - /** - * Provides instances of the concrete class being tested. - * - * @since 1.20 - * - * @return array - */ - public function instanceProvider() { - $instances = array(); - - foreach ( $this->elementInstancesProvider() as $elementInstances ) { - $instances[] = $this->getNew( $elementInstances ); - } - - return $this->arrayWrap( $instances ); - } - - /** - * @since 1.20 - * - * @param array $elements - * - * @return GenericArrayObject - */ - protected function getNew( array $elements = array() ) { - $class = $this->getInstanceClass(); - return new $class( $elements ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testConstructor( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( count( $elements ), $arrayObject->count() ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testIsEmpty( array $elements ) { - $arrayObject = $this->getNew( $elements ); - - $this->assertEquals( $elements === array(), $arrayObject->isEmpty() ); - } - - /** - * @dataProvider instanceProvider - * - * @since 1.20 - * - * @param GenericArrayObject $list - */ - public function testUnset( GenericArrayObject $list ) { - if ( !$list->isEmpty() ) { - $offset = $list->getIterator()->key(); - $count = $list->count(); - $list->offsetUnset( $offset ); - $this->assertEquals( $count - 1, $list->count() ); - } - - if ( !$list->isEmpty() ) { - $offset = $list->getIterator()->key(); - $count = $list->count(); - unset( $list[$offset] ); - $this->assertEquals( $count - 1, $list->count() ); - } - - $exception = null; - try { $list->offsetUnset( 'sdfsedtgsrdysftu' ); } catch ( \Exception $exception ){} - $this->assertInstanceOf( '\Exception', $exception ); - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testAppend( array $elements ) { - $list = $this->getNew(); - - $listSize = count( $elements ); - - foreach ( $elements as $element ) { - $list->append( $element ); - } - - $this->assertEquals( $listSize, $list->count() ); - - $list = $this->getNew(); - - foreach ( $elements as $element ) { - $list[] = $element; - } - - $this->assertEquals( $listSize, $list->count() ); - - $this->checkTypeChecks( function( GenericArrayObject $list, $element ) { - $list->append( $element ); - } ); - } - - /** - * @since 1.20 - * - * @param callback $function - */ - protected function checkTypeChecks( $function ) { - $excption = null; - $list = $this->getNew(); - - $elementClass = $list->getObjectType(); - - foreach ( array( 42, 'foo', array(), new \stdClass(), 4.2 ) as $element ) { - $validValid = $element instanceof $elementClass; - - try{ - call_user_func( $function, $list, $element ); - $valid = true; - } - catch ( InvalidArgumentException $exception ) { - $valid = false; - } - - $this->assertEquals( - $validValid, - $valid, - 'Object of invalid type got successfully added to a GenericArrayObject' - ); - } - } - - /** - * @dataProvider elementInstancesProvider - * - * @since 1.20 - * - * @param array $elements - */ - public function testOffsetSet( array $elements ) { - if ( $elements === array() ) { - $this->assertTrue( true ); - return; - } - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 42, $element ); - $this->assertEquals( $element, $list->offsetGet( 42 ) ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list['oHai'] = $element; - $this->assertEquals( $element, $list['oHai'] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( 9001, $element ); - $this->assertEquals( $element, $list[9001] ); - - $list = $this->getNew(); - - $element = reset( $elements ); - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[0] ); - - $list = $this->getNew(); - $offset = 0; - - foreach ( $elements as $element ) { - $list->offsetSet( null, $element ); - $this->assertEquals( $element, $list[$offset++] ); - } - - $this->assertEquals( count( $elements ), $list->count() ); - - $this->checkTypeChecks( function( GenericArrayObject $list, $element ) { - $list->offsetSet( mt_rand(), $element ); - } ); - } - -} diff --git a/tests/phpunit/includes/libs/IEUrlExtensionTest.php b/tests/phpunit/includes/libs/IEUrlExtensionTest.php deleted file mode 100644 index c6270e90..00000000 --- a/tests/phpunit/includes/libs/IEUrlExtensionTest.php +++ /dev/null @@ -1,118 +0,0 @@ -assertEquals( - 'y', - IEUrlExtension::findIE6Extension( 'x.y' ), - 'Simple extension' - ); - } - - function testSimpleNoExt() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'x' ), - 'No extension' - ); - } - - function testEmpty() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '' ), - 'Empty string' - ); - } - - function testQuestionMark() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '?' ), - 'Question mark only' - ); - } - - function testExtQuestionMark() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '.x?' ), - 'Extension then question mark' - ); - } - - function testQuestionMarkExt() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '?.x' ), - 'Question mark then extension' - ); - } - - function testInvalidChar() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.x*' ), - 'Extension with invalid character' - ); - } - - function testInvalidCharThenExtension() { - $this->assertEquals( - 'x', - IEUrlExtension::findIE6Extension( '*.x' ), - 'Invalid character followed by an extension' - ); - } - - function testMultipleQuestionMarks() { - $this->assertEquals( - 'c', - IEUrlExtension::findIE6Extension( 'a?b?.c?.d?e?f' ), - 'Multiple question marks' - ); - } - - function testExeException() { - $this->assertEquals( - 'd', - IEUrlExtension::findIE6Extension( 'a?b?.exe?.d?.e' ), - '.exe exception' - ); - } - - function testExeException2() { - $this->assertEquals( - 'exe', - IEUrlExtension::findIE6Extension( 'a?b?.exe' ), - '.exe exception 2' - ); - } - - function testHash() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a#b.c' ), - 'Hash character preceding extension' - ); - } - - function testHash2() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( 'a?#b.c' ), - 'Hash character preceding extension 2' - ); - } - - function testDotAtEnd() { - $this->assertEquals( - '', - IEUrlExtension::findIE6Extension( '.' ), - 'Dot at end of string' - ); - } -} diff --git a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php b/tests/phpunit/includes/libs/JavaScriptMinifierTest.php deleted file mode 100644 index f121b018..00000000 --- a/tests/phpunit/includes/libs/JavaScriptMinifierTest.php +++ /dev/null @@ -1,170 +0,0 @@ - bar", "" ), - array( "--> Foo", "" ), - array( "x --> y", "x-->y" ), - - // Semicolon insertion - array( "(function(){return\nx;})", "(function(){return\nx;})" ), - array( "throw\nx;", "throw\nx;" ), - array( "while(p){continue\nx;}", "while(p){continue\nx;}" ), - array( "while(p){break\nx;}", "while(p){break\nx;}" ), - array( "var\nx;", "var x;" ), - array( "x\ny;", "x\ny;" ), - array( "x\n++y;", "x\n++y;" ), - array( "x\n!y;", "x\n!y;" ), - array( "x\n{y}", "x\n{y}" ), - array( "x\n+y;", "x+y;" ), - array( "x\n(y);", "x(y);" ), - array( "5.\nx;", "5.\nx;" ), - array( "0xFF.\nx;", "0xFF.x;" ), - array( "5.3.\nx;", "5.3.x;" ), - - // Semicolon insertion between an expression having an inline - // comment after it, and a statement on the next line (bug 27046). - array( "var a = this //foo bar \n for ( b = 0; c < d; b++ ) {}", "var a=this\nfor(b=0;cparse( $minified, 'minify-test.js', 1 ); - - $this->assertEquals( $expectedOutput, $minified, "Minified output should be in the form expected." ); - } - - function provideBug32548() { - return array( - array( - // This one gets interpreted all together by the prior code; - // no break at the 'E' happens. - '1.23456789E55', - ), - array( - // This one breaks under the bad code; splits between 'E' and '+' - '1.23456789E+5', - ), - array( - // This one breaks under the bad code; splits between 'E' and '-' - '1.23456789E-5', - ), - ); - } - - /** - * @dataProvider provideBug32548 - */ - function testBug32548Exponent( $num ) { - // Long line breaking was being incorrectly done between the base and - // exponent part of a number, causing a syntax error. The line should - // instead break at the start of the number. - $prefix = 'var longVarName' . str_repeat( '_', 973 ) . '='; - $suffix = ',shortVarName=0;'; - - $input = $prefix . $num . $suffix; - $expected = $prefix . "\n" . $num . $suffix; - - $minified = JavaScriptMinifier::minify( $input ); - - $this->assertEquals( $expected, $minified, "Line breaks must not occur in middle of exponent"); - } -} diff --git a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php b/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php deleted file mode 100644 index 88f87ef9..00000000 --- a/tests/phpunit/includes/media/BitmapMetadataHandlerTest.php +++ /dev/null @@ -1,146 +0,0 @@ -filePath = __DIR__ . '/../../data/media/'; - } - - /** - * Test if having conflicting metadata values from different - * types of metadata, that the right one takes precedence. - * - * Basically the file has IPTC and XMP metadata, the - * IPTC should override the XMP, except for the multilingual - * translation (to en) where XMP should win. - */ - public function testMultilingualCascade() { - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - if ( !wfDl( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - global $wgShowEXIF; - $oldExif = $wgShowEXIF; - $wgShowEXIF = true; - - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - '/Xmp-exif-multilingual_test.jpg' ); - - $expected = array( - 'x-default' => 'right(iptc)', - 'en' => 'right translation', - '_type' => 'lang' - ); - - $this->assertArrayHasKey( 'ImageDescription', $meta, - 'Did not extract any ImageDescription info?!' ); - - $this->assertEquals( $expected, $meta['ImageDescription'] ); - - $wgShowEXIF = $oldExif; - } - - /** - * Test for jpeg comments are being handled by - * BitmapMetadataHandler correctly. - * - * There's more extensive tests of comment extraction in - * JpegMetadataExtractorTests.php - */ - public function testJpegComment() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'jpeg-comment-utf.jpg' ); - - $this->assertEquals( 'UTF-8 JPEG Comment — ¼', - $meta['JPEGFileComment'][0] ); - } - - /** - * Make sure a bad iptc block doesn't stop the other metadata - * from being extracted. - */ - public function testBadIPTC() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'iptc-invalid-psir.jpg' ); - $this->assertEquals( 'Created with GIMP', $meta['JPEGFileComment'][0] ); - } - - public function testIPTCDates() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'iptc-timetest.jpg' ); - - $this->assertEquals( '2020:07:14 01:36:05', $meta['DateTimeDigitized'] ); - $this->assertEquals( '1997:03:02 00:01:02', $meta['DateTimeOriginal'] ); - } - /** - * File has an invalid time (+ one valid but really weird time) - * that shouldn't be included - */ - public function testIPTCDatesInvalid() { - $meta = BitmapMetadataHandler::Jpeg( $this->filePath . - 'iptc-timetest-invalid.jpg' ); - - $this->assertEquals( '1845:03:02 00:01:02', $meta['DateTimeOriginal'] ); - $this->assertFalse( isset( $meta['DateTimeDigitized'] ) ); - } - - /** - * XMP data should take priority over iptc data - * when hash has been updated, but not when - * the hash is wrong. - */ - public function testMerging() { - $merger = new BitmapMetadataHandler(); - $merger->addMetadata( array( 'foo' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'bar' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'baz' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'fred' => 'xmp' ), 'xmp-general' ); - $merger->addMetadata( array( 'foo' => 'iptc (hash)' ), 'iptc-good-hash' ); - $merger->addMetadata( array( 'bar' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'baz' => 'iptc (bad hash)' ), 'iptc-bad-hash' ); - $merger->addMetadata( array( 'fred' => 'iptc (no hash)' ), 'iptc-no-hash' ); - $merger->addMetadata( array( 'baz' => 'exif' ), 'exif' ); - - $actual = $merger->getMetadataArray(); - $expected = array( - 'foo' => 'xmp', - 'bar' => 'iptc (bad hash)', - 'baz' => 'exif', - 'fred' => 'xmp', - ); - $this->assertEquals( $expected, $actual ); - } - - public function testPNGXMP() { - if ( !wfDl( 'xml' ) ) { - $this->markTestSkipped( "This test needs the xml extension." ); - } - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'xmp.png' ); - $expected = array ( - 'frameCount' => 0, - 'loopCount' => 1, - 'duration' => 0, - 'bitDepth' => 1, - 'colorType' => 'index-coloured', - 'metadata' => array ( - 'SerialNumber' => '123456789', - '_MW_PNG_VERSION' => 1, - ), - ); - $this->assertEquals( $expected, $result ); - } - public function testPNGNative() { - $handler = new BitmapMetadataHandler(); - $result = $handler->png( $this->filePath . 'Png-native-test.png' ); - $expected = 'http://example.com/url'; - $this->assertEquals( $expected, $result['metadata']['Identifier']['x-default'] ); - } - public function testTiffByteOrder() { - $handler = new BitmapMetadataHandler(); - $res = $handler->getTiffByteOrder( $this->filePath . 'test.tiff' ); - $this->assertEquals( 'LE', $res ); - } - -} diff --git a/tests/phpunit/includes/media/BitmapScalingTest.php b/tests/phpunit/includes/media/BitmapScalingTest.php deleted file mode 100644 index 11d9dc47..00000000 --- a/tests/phpunit/includes/media/BitmapScalingTest.php +++ /dev/null @@ -1,151 +0,0 @@ -oldMaxImageArea = $wgMaxImageArea; - $this->oldCustomConvertCommand = $wgCustomConvertCommand; - $wgMaxImageArea = 1.25e7; // 3500x3500 - $wgCustomConvertCommand = 'dummy'; // Set so that we don't get client side rendering - } - function tearDown() { - global $wgMaxImageArea, $wgCustomConvertCommand; - $wgMaxImageArea = $this->oldMaxImageArea; - $wgCustomConvertCommand = $this->oldCustomConvertCommand; - } - /** - * @dataProvider provideNormaliseParams - */ - function testNormaliseParams( $fileDimensions, $expectedParams, $params, $msg ) { - $file = new FakeDimensionFile( $fileDimensions ); - $handler = new BitmapHandler; - $valid = $handler->normaliseParams( $file, $params ); - $this->assertTrue( $valid ); - $this->assertEquals( $expectedParams, $params, $msg ); - } - - function provideNormaliseParams() { - return array( - /* Regular resize operations */ - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512 ), - 'Resizing with width set', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 512, 'height' => 768 ), - 'Resizing with height set too high', - ), - array( - array( 1024, 768 ), - array( - 'width' => 512, 'height' => 384, - 'physicalWidth' => 512, 'physicalHeight' => 384, - 'page' => 1, - ), - array( 'width' => 1024, 'height' => 384 ), - 'Resizing with height set', - ), - - /* Very tall images */ - array( - array( 1000, 100 ), - array( - 'width' => 5, 'height' => 1, - 'physicalWidth' => 5, 'physicalHeight' => 1, - 'page' => 1, - ), - array( 'width' => 5 ), - 'Very wide image', - ), - - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 10, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 1 ), - 'Very high image', - ), - array( - array( 100, 1000 ), - array( - 'width' => 1, 'height' => 5, - 'physicalWidth' => 1, 'physicalHeight' => 10, - 'page' => 1, - ), - array( 'width' => 10, 'height' => 5 ), - 'Very high image with height set', - ), - /* Max image area */ - array( - array( 4000, 4000 ), - array( - 'width' => 5000, 'height' => 5000, - 'physicalWidth' => 4000, 'physicalHeight' => 4000, - 'page' => 1, - ), - array( 'width' => 5000 ), - 'Bigger than max image size but doesn\'t need scaling', - ), - ); - } - function testTooBigImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $handler = new BitmapHandler; - $params = array( 'width' => '3700' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - function testTooBigMustRenderImage() { - $file = new FakeDimensionFile( array( 4000, 4000 ) ); - $file->mustRender = true; - $handler = new BitmapHandler; - $params = array( 'width' => '5000' ); // Still bigger than max size. - $this->assertEquals( 'TransformParameterError', - get_class( $handler->doTransform( $file, 'dummy path', '', $params ) ) ); - } - - function testImageArea() { - $file = new FakeDimensionFile( array( 7, 9 ) ); - $handler = new BitmapHandler; - $this->assertEquals( 63, $handler->getImageArea( $file ) ); - } -} - -class FakeDimensionFile extends File { - public $mustRender = false; - - public function __construct( $dimensions ) { - parent::__construct( Title::makeTitle( NS_FILE, 'Test' ), - new NullRepo( null ) ); - - $this->dimensions = $dimensions; - } - public function getWidth( $page = 1 ) { - return $this->dimensions[0]; - } - public function getHeight( $page = 1 ) { - return $this->dimensions[1]; - } - public function mustRender() { - return $this->mustRender; - } - public function getPath() { - return ''; - } -} diff --git a/tests/phpunit/includes/media/ExifBitmapTest.php b/tests/phpunit/includes/media/ExifBitmapTest.php deleted file mode 100644 index b2f6b7ba..00000000 --- a/tests/phpunit/includes/media/ExifBitmapTest.php +++ /dev/null @@ -1,100 +0,0 @@ -showExif = $wgShowEXIF; - $wgShowEXIF = true; - $this->handler = new ExifBitmapHandler; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - } - - public function tearDown() { - global $wgShowEXIF; - $wgShowEXIF = $this->showExif; - } - - public function testIsOldBroken() { - $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::OLD_BROKEN_FILE ); - $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); - } - public function testIsBrokenFile() { - $res = $this->handler->isMetadataValid( null, ExifBitmapHandler::BROKEN_FILE ); - $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); - } - public function testIsInvalid() { - $res = $this->handler->isMetadataValid( null, 'Something Invalid Here.' ); - $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); - } - public function testGoodMetadata() { - $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; - $res = $this->handler->isMetadataValid( null, $meta ); - $this->assertEquals( ExifBitmapHandler::METADATA_GOOD, $res ); - } - public function testIsOldGood() { - $meta = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}'; - $res = $this->handler->isMetadataValid( null, $meta ); - $this->assertEquals( ExifBitmapHandler::METADATA_COMPATIBLE, $res ); - } - // Handle metadata from paged tiff handler (gotten via instant commons) - // gracefully. - public function testPagedTiffHandledGracefully() { - $meta = 'a:6:{s:9:"page_data";a:1:{i:1;a:5:{s:5:"width";i:643;s:6:"height";i:448;s:5:"alpha";s:4:"true";s:4:"page";i:1;s:6:"pixels";i:288064;}}s:10:"page_count";i:1;s:10:"first_page";i:1;s:9:"last_page";i:1;s:4:"exif";a:9:{s:10:"ImageWidth";i:643;s:11:"ImageLength";i:448;s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:4;s:12:"RowsPerStrip";i:50;s:19:"PlanarConfiguration";i:1;s:22:"MEDIAWIKI_EXIF_VERSION";i:1;}s:21:"TIFF_METADATA_VERSION";s:3:"1.4";}'; - $res = $this->handler->isMetadataValid( null, $meta ); - $this->assertEquals( ExifBitmapHandler::METADATA_BAD, $res ); - } - - function testConvertMetadataLatest() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'MEDIAWIKI_EXIF_VERSION' => 2 - ); - $res = $this->handler->convertMetadataVersion( $metadata, 2 ); - $this->assertEquals( $metadata, $res ); - } - function testConvertMetadataToOld() { - $metadata = array( - 'foo' => array( 'First', 'Second', '_type' => 'ol' ), - 'bar' => array( 'First', 'Second', '_type' => 'ul' ), - 'baz' => array( 'First', 'Second' ), - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'foo' => "\n#First\n#Second", - 'bar' => "\n*First\n*Second", - 'baz' => "\n*First\n*Second", - 'fred' => 'Single', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - function testConvertMetadataSoftware() { - $metadata = array( - 'Software' => array( array('GIMP', '1.1' ) ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => 'GIMP (Version 1.1)', - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } - function testConvertMetadataSoftwareNormal() { - $metadata = array( - 'Software' => array( "GIMP 1.2", "vim" ), - 'MEDIAWIKI_EXIF_VERSION' => 2, - ); - $expected = array( - 'Software' => "\n*GIMP 1.2\n*vim", - 'MEDIAWIKI_EXIF_VERSION' => 1, - ); - $res = $this->handler->convertMetadataVersion( $metadata, 1 ); - $this->assertEquals( $expected, $res ); - } -} diff --git a/tests/phpunit/includes/media/ExifRotationTest.php b/tests/phpunit/includes/media/ExifRotationTest.php deleted file mode 100644 index 6af52dd1..00000000 --- a/tests/phpunit/includes/media/ExifRotationTest.php +++ /dev/null @@ -1,260 +0,0 @@ -handler = new BitmapHandler(); - $filePath = __DIR__ . '/../../data/media'; - - $tmpDir = $this->getNewTempDirectory(); - - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'temp-thumb' => $tmpDir, 'data' => $filePath ) - ) ) - ) ); - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - global $wgShowEXIF; - $this->show = $wgShowEXIF; - $wgShowEXIF = true; - - global $wgEnableAutoRotation; - $this->oldAuto = $wgEnableAutoRotation; - $wgEnableAutoRotation = true; - } - - public function tearDown() { - global $wgShowEXIF, $wgEnableAutoRotation; - $wgShowEXIF = $this->show; - $wgEnableAutoRotation = $this->oldAuto; - - parent::tearDown(); - } - - /** - * - * @dataProvider providerFiles - */ - function testMetadata( $name, $type, $info ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - $file = $this->dataFile( $name, $type ); - $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); - $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - } - - /** - * - * @dataProvider providerFiles - */ - function testRotationRendering( $name, $type, $info, $thumbs ) { - if ( !BitmapHandler::canRotate() ) { - $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." ); - } - foreach( $thumbs as $size => $out ) { - if( preg_match('/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException('bogus test data format ' . $size); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ($out[0] > $info['width']) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size"); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size"); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size"); - } - } - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } - - function providerFiles() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 768, // as rotated - 'height' => 1024, // as rotated - ), - array( - '800x600px' => array( 450, 600 ), - '9999x800px' => array( 600, 800 ), - '800px' => array( 800, 1067 ), - '600px' => array( 600, 800 ), - ) - ) - ); - } - - /** - * Same as before, but with auto-rotation disabled. - * @dataProvider providerFilesNoAutoRotate - */ - function testMetadataNoAutoRotate( $name, $type, $info ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; - - $file = $this->dataFile( $name, $type ); - $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" ); - $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" ); - - $wgEnableAutoRotation = true; - } - - /** - * - * @dataProvider providerFilesNoAutoRotate - */ - function testRotationRenderingNoAutoRotate( $name, $type, $info, $thumbs ) { - global $wgEnableAutoRotation; - $wgEnableAutoRotation = false; - - foreach( $thumbs as $size => $out ) { - if( preg_match('/^(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - ); - } elseif ( preg_match( '/^(\d+)x(\d+)px$/', $size, $matches ) ) { - $params = array( - 'width' => $matches[1], - 'height' => $matches[2] - ); - } else { - throw new MWException('bogus test data format ' . $size); - } - - $file = $this->dataFile( $name, $type ); - $thumb = $file->transform( $params, File::RENDER_NOW | File::RENDER_FORCE ); - - $this->assertEquals( $out[0], $thumb->getWidth(), "$name: thumb reported width check for $size" ); - $this->assertEquals( $out[1], $thumb->getHeight(), "$name: thumb reported height check for $size" ); - - $gis = getimagesize( $thumb->getLocalCopyPath() ); - if ($out[0] > $info['width']) { - // Physical image won't be scaled bigger than the original. - $this->assertEquals( $info['width'], $gis[0], "$name: thumb actual width check for $size"); - $this->assertEquals( $info['height'], $gis[1], "$name: thumb actual height check for $size"); - } else { - $this->assertEquals( $out[0], $gis[0], "$name: thumb actual width check for $size"); - $this->assertEquals( $out[1], $gis[1], "$name: thumb actual height check for $size"); - } - } - $wgEnableAutoRotation = true; - } - - function providerFilesNoAutoRotate() { - return array( - array( - 'landscape-plain.jpg', - 'image/jpeg', - array( - 'width' => 1024, - 'height' => 768, - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ), - array( - 'portrait-rotated.jpg', - 'image/jpeg', - array( - 'width' => 1024, // since not rotated - 'height' => 768, // since not rotated - ), - array( - '800x600px' => array( 800, 600 ), - '9999x800px' => array( 1067, 800 ), - '800px' => array( 800, 600 ), - '600px' => array( 600, 450 ), - ) - ) - ); - } - - - const TEST_WIDTH = 100; - const TEST_HEIGHT = 200; - - /** - * @dataProvider provideBitmapExtractPreRotationDimensions - */ - function testBitmapExtractPreRotationDimensions( $rotation, $expected ) { - $result = $this->handler->extractPreRotationDimensions( array( - 'physicalWidth' => self::TEST_WIDTH, - 'physicalHeight' => self::TEST_HEIGHT, - ), $rotation ); - $this->assertEquals( $expected, $result ); - } - - function provideBitmapExtractPreRotationDimensions() { - return array( - array( - 0, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 90, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - array( - 180, - array( self::TEST_WIDTH, self::TEST_HEIGHT ) - ), - array( - 270, - array( self::TEST_HEIGHT, self::TEST_WIDTH ) - ), - ); - } -} - diff --git a/tests/phpunit/includes/media/ExifTest.php b/tests/phpunit/includes/media/ExifTest.php deleted file mode 100644 index 045777d7..00000000 --- a/tests/phpunit/includes/media/ExifTest.php +++ /dev/null @@ -1,48 +0,0 @@ -mediaPath = __DIR__ . '/../../data/media/'; - - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - global $wgShowEXIF; - $this->showExif = $wgShowEXIF; - $wgShowEXIF = true; - } - - public function tearDown() { - global $wgShowEXIF; - $wgShowEXIF = $this->showExif; - } - - public function testGPSExtraction() { - $filename = $this->mediaPath . 'exif-gps.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - $expected = array( - 'GPSLatitude' => 88.5180555556, - 'GPSLongitude' => -21.12357, - 'GPSAltitude' => -3.141592653, - 'GPSDOP' => '5/1', - 'GPSVersionID' => '2.2.0.0', - ); - $this->assertEquals( $expected, $data, '', 0.0000000001 ); - } - - public function testUnicodeUserComment() { - $filename = $this->mediaPath . 'exif-user-comment.jpg'; - $seg = JpegMetadataExtractor::segmentSplitter( $filename ); - $exif = new Exif( $filename, $seg['byteOrder'] ); - $data = $exif->getFilteredData(); - - $expected = array( - 'UserComment' => 'test⁔comment' - ); - $this->assertEquals( $expected, $data ); - } - - -} diff --git a/tests/phpunit/includes/media/FormatMetadataTest.php b/tests/phpunit/includes/media/FormatMetadataTest.php deleted file mode 100644 index 6ade6702..00000000 --- a/tests/phpunit/includes/media/FormatMetadataTest.php +++ /dev/null @@ -1,52 +0,0 @@ -markTestSkipped( "This test needs the exif extension." ); - } - $filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - global $wgShowEXIF; - $this->show = $wgShowEXIF; - $wgShowEXIF = true; - } - public function tearDown() { - global $wgShowEXIF; - $wgShowEXIF = $this->show; - } - - public function testInvalidDate() { - $file = $this->dataFile( 'broken_exif_date.jpg', 'image/jpeg' ); - - // Throws an error if bug hit - $meta = $file->formatMetadata(); - $this->assertNotEquals( false, $meta, 'Valid metadata extracted' ); - - // Find date exif entry - $this->assertArrayHasKey( 'visible', $meta ); - $dateIndex = null; - foreach ( $meta['visible'] as $i => $data ) { - if ( $data['id'] == 'exif-datetimeoriginal' ) { - $dateIndex = $i; - } - } - $this->assertNotNull( $dateIndex, 'Date entry exists in metadata' ); - $this->assertEquals( '0000:01:00 00:02:27', - $meta['visible'][$dateIndex]['value'], - 'File with invalid date metadata (bug 29471)' ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php b/tests/phpunit/includes/media/GIFMetadataExtractorTest.php deleted file mode 100644 index 650fdd5c..00000000 --- a/tests/phpunit/includes/media/GIFMetadataExtractorTest.php +++ /dev/null @@ -1,96 +0,0 @@ -mediaPath = __DIR__ . '/../../data/media/'; - } - /** - * Put in a file, and see if the metadata coming out is as expected. - * @param $filename String - * @param $expected Array The extracted metadata. - * @dataProvider dataGetMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $actual = GIFMetadataExtractor::getMetadata( $this->mediaPath . $filename ); - $this->assertEquals( $expected, $actual ); - } - public function dataGetMetadata() { - - $xmpNugget = << - - - - - The interwebs - - - - Bawolff - - - A file to test GIF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -EOF; - $xmpNugget = str_replace( "\r", '', $xmpNugget ); // Windows compat - - return array( - array( 'nonanimated.gif', array( - 'comment' => array( 'GIF test file ⁕ Created with GIMP' ), - 'duration' => 0.1, - 'frameCount' => 1, - 'looped' => false, - 'xmp' => '', - ) - ), - array( 'animated.gif', array( - 'comment' => array( 'GIF test file . Created with GIMP' ), - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'xmp' => '', - ) - ), - - array( 'animated-xmp.gif', array( - 'xmp' => $xmpNugget, - 'duration' => 2.4, - 'frameCount' => 4, - 'looped' => true, - 'comment' => array( 'GIƒ·test·file' ), - ) - ), - ); - } -} diff --git a/tests/phpunit/includes/media/GIFTest.php b/tests/phpunit/includes/media/GIFTest.php deleted file mode 100644 index 5dcbeee0..00000000 --- a/tests/phpunit/includes/media/GIFTest.php +++ /dev/null @@ -1,98 +0,0 @@ -filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new GIFHandler(); - } - - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( GIFHandler::BROKEN_FILE, $res ); - } - /** - * @param $filename String basename of the file to check - * @param $expected boolean Expected result. - * @dataProvider dataIsAnimated - */ - public function testIsAnimanted( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/gif' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - public function dataIsAnimated() { - return array( - array( 'animated.gif', true ), - array( 'nonanimated.gif', false ), - ); - } - - /** - * @param $filename String - * @param $expected Integer Total image area - * @dataProvider dataGetImageArea - */ - public function testGetImageArea( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/gif' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - public function dataGetImageArea() { - return array( - array( 'animated.gif', 5400 ), - array( 'nonanimated.gif', 1350 ), - ); - } - - /** - * @param $metadata String Serialized metadata - * @param $expected Integer One of the class constants of GIFHandler - * @dataProvider dataIsMetadataValid - */ - public function testIsMetadataValid( $metadata, $expected ) { - $actual = $this->handler->isMetadataValid( null, $metadata ); - $this->assertEquals( $expected, $actual ); - } - public function dataIsMetadataValid() { - return array( - array( GIFHandler::BROKEN_FILE, GIFHandler::METADATA_GOOD ), - array( '', GIFHandler::METADATA_BAD ), - array( null, GIFHandler::METADATA_BAD ), - array( 'Something invalid!', GIFHandler::METADATA_BAD ), - array( 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}', GIFHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider dataGetMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/gif' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); - $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - } - - public function dataGetMetadata() { - return array( - array( 'nonanimated.gif', 'a:4:{s:10:"frameCount";i:1;s:6:"looped";b:0;s:8:"duration";d:0.1000000000000000055511151231257827021181583404541015625;s:8:"metadata";a:2:{s:14:"GIFFileComment";a:1:{i:0;s:35:"GIF test file ⁕ Created with GIMP";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - array( 'animated-xmp.gif', 'a:4:{s:10:"frameCount";i:4;s:6:"looped";b:1;s:8:"duration";d:2.399999999999999911182158029987476766109466552734375;s:8:"metadata";a:5:{s:6:"Artist";s:7:"Bawolff";s:16:"ImageDescription";a:2:{s:9:"x-default";s:18:"A file to test GIF";s:5:"_type";s:4:"lang";}s:15:"SublocationDest";s:13:"The interwebs";s:14:"GIFFileComment";a:1:{i:0;s:16:"GIƒ·test·file";}s:15:"_MW_GIF_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/IPTCTest.php b/tests/phpunit/includes/media/IPTCTest.php deleted file mode 100644 index ec6deeb8..00000000 --- a/tests/phpunit/includes/media/IPTCTest.php +++ /dev/null @@ -1,55 +0,0 @@ -assertEquals( 'UTF-8', $res ); - } - - public function testIPTCParseNoCharset88591() { - // basically IPTC for keyword with value of 0xBC which is 1/4 in iso-8859-1 - // This data doesn't specify a charset. We're supposed to guess - // (which basically means utf-8 if valid, windows 1252 (iso 8859-1) if not) - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x06\x1c\x02\x19\x00\x01\xBC"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼' ), $res['Keywords'] ); - } - /* This one contains a sequence that's valid iso 8859-1 but not valid utf8 */ - /* \xC3 = Ã, \xB8 = ¸ */ - public function testIPTCParseNoCharset88591b() { - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x09\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( 'ÃÃø' ), $res['Keywords'] ); - } - /* Same as testIPTCParseNoCharset88591b, but forcing the charset to utf-8. - * What should happen is the first "\xC3\xC3" should be dropped as invalid, - * leaving \xC3\xB8, which is ø - */ - public function testIPTCParseForcedUTFButInvalid() { - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x11\x1c\x02\x19\x00\x04\xC3\xC3\xC3\xB8" - . "\x1c\x01\x5A\x00\x03\x1B\x25\x47"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( 'ø' ), $res['Keywords'] ); - } - public function testIPTCParseNoCharsetUTF8() { - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x07\x1c\x02\x19\x00\x02¼"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼' ), $res['Keywords'] ); - } - // Testing something that has 2 values for keyword - public function testIPTCParseMulti() { - $iptcData = /* identifier */ "Photoshop 3.0\08BIM\4\4" - /* length */ . "\0\0\0\0\0\x0D" - . "\x1c\x02\x19" . "\x00\x01" . "\xBC" - . "\x1c\x02\x19" . "\x00\x02" . "\xBC\xBD"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼', '¼½' ), $res['Keywords'] ); - } - public function testIPTCParseUTF8() { - // This has the magic "\x1c\x01\x5A\x00\x03\x1B\x25\x47" which marks content as UTF8. - $iptcData = "Photoshop 3.0\08BIM\4\4\0\0\0\0\0\x0F\x1c\x02\x19\x00\x02¼\x1c\x01\x5A\x00\x03\x1B\x25\x47"; - $res = IPTC::Parse( $iptcData ); - $this->assertEquals( array( '¼' ), $res['Keywords'] ); - } - -} diff --git a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php b/tests/phpunit/includes/media/JpegMetadataExtractorTest.php deleted file mode 100644 index 41d81190..00000000 --- a/tests/phpunit/includes/media/JpegMetadataExtractorTest.php +++ /dev/null @@ -1,94 +0,0 @@ -filePath = __DIR__ . '/../../data/media/'; - } - - /** - * We also use this test to test padding bytes don't - * screw stuff up - * - * @param $file filename - * - * @dataProvider dataUtf8Comment - */ - public function testUtf8Comment( $file ) { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . $file ); - $this->assertEquals( array( 'UTF-8 JPEG Comment — ¼' ), $res['COM'] ); - } - public function dataUtf8Comment() { - return array( - array( 'jpeg-comment-utf.jpg' ), - array( 'jpeg-padding-even.jpg' ), - array( 'jpeg-padding-odd.jpg' ), - ); - } - /** The file is iso-8859-1, but it should get auto converted */ - public function testIso88591Comment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-iso8859-1.jpg' ); - $this->assertEquals( array( 'ISO-8859-1 JPEG Comment - ¼' ), $res['COM'] ); - } - /** Comment values that are non-textual (random binary junk) should not be shown. - * The example test file has a comment with a 0x5 byte in it which is a control character - * and considered binary junk for our purposes. - */ - public function testBinaryCommentStripped() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-binary.jpg' ); - $this->assertEmpty( $res['COM'] ); - } - /* Very rarely a file can have multiple comments. - * Order of comments is based on order inside the file. - */ - public function testMultipleComment() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-comment-multiple.jpg' ); - $this->assertEquals( array( 'foo', 'bar' ), $res['COM'] ); - } - public function testXMPExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - public function testPSIRExtraction() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $expected = '50686f746f73686f7020332e30003842494d04040000000000181c02190004746573741c02190003666f6f1c020000020004'; - $this->assertEquals( $expected, bin2hex( $res['PSIR'][0] ) ); - } - public function testXMPExtractionAltAppId() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-alt.jpg' ); - $expected = file_get_contents( $this->filePath . 'jpeg-xmp-psir.xmp' ); - $this->assertEquals( $expected, $res['XMP'] ); - } - - - public function testIPTCHashComparisionNoHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-xmp-psir.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-no-hash', $res ); - } - public function testIPTCHashComparisionBadHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-bad-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-bad-hash', $res ); - } - public function testIPTCHashComparisionGoodHash() { - $segments = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'jpeg-iptc-good-hash.jpg' ); - $res = JpegMetadataExtractor::doPSIR( $segments['PSIR'][0] ); - - $this->assertEquals( 'iptc-good-hash', $res ); - } - public function testExifByteOrder() { - $res = JpegMetadataExtractor::segmentSplitter( $this->filePath . 'exif-user-comment.jpg' ); - $expected = 'BE'; - $this->assertEquals( $expected, $res['byteOrder'] ); - } -} diff --git a/tests/phpunit/includes/media/JpegTest.php b/tests/phpunit/includes/media/JpegTest.php deleted file mode 100644 index ea007f90..00000000 --- a/tests/phpunit/includes/media/JpegTest.php +++ /dev/null @@ -1,31 +0,0 @@ -filePath = __DIR__ . '/../../data/media/'; - if ( !wfDl( 'exif' ) ) { - $this->markTestSkipped( "This test needs the exif extension." ); - } - global $wgShowEXIF; - $this->show = $wgShowEXIF; - $wgShowEXIF = true; - } - public function tearDown() { - global $wgShowEXIF; - $wgShowEXIF = $this->show; - } - - public function testInvalidFile() { - $jpeg = new JpegHandler; - $res = $jpeg->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - public function testJpegMetadataExtraction() { - $h = new JpegHandler; - $res = $h->getMetadata( null, $this->filePath . 'test.jpg' ); - $expected = 'a:7:{s:16:"ImageDescription";s:9:"Test file";s:11:"XResolution";s:4:"72/1";s:11:"YResolution";s:4:"72/1";s:14:"ResolutionUnit";i:2;s:16:"YCbCrPositioning";i:1;s:15:"JPEGFileComment";a:1:{i:0;s:17:"Created with GIMP";}s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; - - // Unserialize in case serialization format ever changes. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/MediaHandlerTest.php b/tests/phpunit/includes/media/MediaHandlerTest.php deleted file mode 100644 index 99df4f80..00000000 --- a/tests/phpunit/includes/media/MediaHandlerTest.php +++ /dev/null @@ -1,50 +0,0 @@ - 50, - 'height' => 50, - 'tests' => array( - 50 => 50, - 17 => 17, - 18 => 18 ) ), - array( - 'width' => 366, - 'height' => 300, - 'tests' => array( - 50 => 61, - 17 => 21, - 18 => 22 ) ), - array( - 'width' => 300, - 'height' => 366, - 'tests' => array( - 50 => 41, - 17 => 14, - 18 => 15 ) ), - array( - 'width' => 100, - 'height' => 400, - 'tests' => array( - 50 => 12, - 17 => 4, - 18 => 4 ) ) ); - foreach ( $vals as $row ) { - $tests = $row['tests']; - $height = $row['height']; - $width = $row['width']; - foreach ( $tests as $max => $expected ) { - $y = round( $expected * $height / $width ); - $result = MediaHandler::fitBoxWidth( $width, $height, $max ); - $y2 = round( $result * $height / $width ); - $this->assertEquals( $expected, - $result, - "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" ); - } - } - } -} - - diff --git a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php b/tests/phpunit/includes/media/PNGMetadataExtractorTest.php deleted file mode 100644 index 1b1b2ec3..00000000 --- a/tests/phpunit/includes/media/PNGMetadataExtractorTest.php +++ /dev/null @@ -1,141 +0,0 @@ -filePath = __DIR__ . '/../../data/media/'; - } - /** - * Tests zTXt tag (compressed textual metadata) - */ - function testPngNativetZtxt() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "foo bar baz foo foo foo foof foo foo foo foo"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Make', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Make'] ); - - $this->assertEquals( $expected, $meta['Make']['x-default'] ); - } - - /** - * Test tEXt tag (Uncompressed textual metadata) - */ - function testPngNativeText() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - $expected = "Some long image desc"; - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'ImageDescription', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['ImageDescription'] ); - $this->assertArrayHasKey( '_type', $meta['ImageDescription'] ); - - $this->assertEquals( $expected, $meta['ImageDescription']['x-default'] ); - } - - /** - * tEXt tags must be encoded iso-8859-1 (vs iTXt which are utf-8) - * Make sure non-ascii characters get converted properly - */ - function testPngNativeTextNonAscii() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - // Note the Copyright symbol here is a utf-8 one - // (aka \xC2\xA9) where in the file its iso-8859-1 - // encoded as just \xA9. - $expected = "© 2010 Bawolff"; - - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - $this->assertArrayHasKey( 'Copyright', $meta ); - $this->assertArrayHasKey( 'x-default', $meta['Copyright'] ); - - $this->assertEquals( $expected, $meta['Copyright']['x-default'] ); - } - - /** - * Test extraction of pHYs tags, which can tell what the - * actual resolution of the image is (aka in dots per meter). - function testPngPhysTag () { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertArrayHasKey( 'text', $meta ); - $meta = $meta['text']; - - $this->assertEquals( '2835/100', $meta['XResolution'] ); - $this->assertEquals( '2835/100', $meta['YResolution'] ); - $this->assertEquals( 3, $meta['ResolutionUnit'] ); // 3 = cm - } - - /** - * Given a normal static PNG, check the animation metadata returned. - */ - function testStaticPngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 0, $meta['frameCount'] ); - $this->assertEquals( 1, $meta['loopCount'] ); - $this->assertEquals( 0, $meta['duration'] ); - } - - /** - * Given an animated APNG image file - * check it gets animated metadata right. - */ - function testApngAnimationMetadata() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Animated_PNG_example_bouncing_beach_ball.png' ); - - $this->assertEquals( 20, $meta['frameCount'] ); - // Note loop count of 0 = infinity - $this->assertEquals( 0, $meta['loopCount'] ); - $this->assertEquals( 1.5, $meta['duration'], '', 0.00001 ); - } - - function testPngBitDepth8() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 8, $meta['bitDepth'] ); - } - function testPngBitDepth1() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - '1bit-png.png' ); - $this->assertEquals( 1, $meta['bitDepth'] ); - } - - - function testPngIndexColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'Png-native-test.png' ); - - $this->assertEquals( 'index-coloured', $meta['colorType'] ); - } - function testPngRgbColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-png.png' ); - $this->assertEquals( 'truecolour-alpha', $meta['colorType'] ); - } - function testPngRgbNoAlphaColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'rgb-na-png.png' ); - $this->assertEquals( 'truecolour', $meta['colorType'] ); - } - function testPngGreyscaleColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'greyscale-png.png' ); - $this->assertEquals( 'greyscale-alpha', $meta['colorType'] ); - } - function testPngGreyscaleNoAlphaColour() { - $meta = PNGMetadataExtractor::getMetadata( $this->filePath . - 'greyscale-na-png.png' ); - $this->assertEquals( 'greyscale', $meta['colorType'] ); - } - -} diff --git a/tests/phpunit/includes/media/PNGTest.php b/tests/phpunit/includes/media/PNGTest.php deleted file mode 100644 index fe73c9c7..00000000 --- a/tests/phpunit/includes/media/PNGTest.php +++ /dev/null @@ -1,100 +0,0 @@ -filePath = __DIR__ . '/../../data/media'; - $this->backend = new FSFileBackend( array( - 'name' => 'localtesting', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( 'data' => $this->filePath ) - ) ); - $this->repo = new FSRepo( array( - 'name' => 'temp', - 'url' => 'http://localhost/thumbtest', - 'backend' => $this->backend - ) ); - $this->handler = new PNGHandler(); - } - - public function testInvalidFile() { - $res = $this->handler->getMetadata( null, $this->filePath . '/README' ); - $this->assertEquals( PNGHandler::BROKEN_FILE, $res ); - } - /** - * @param $filename String basename of the file to check - * @param $expected boolean Expected result. - * @dataProvider dataIsAnimated - */ - public function testIsAnimanted( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/png' ); - $actual = $this->handler->isAnimatedImage( $file ); - $this->assertEquals( $expected, $actual ); - } - public function dataIsAnimated() { - return array( - array( 'Animated_PNG_example_bouncing_beach_ball.png', true ), - array( '1bit-png.png', false ), - ); - } - - /** - * @param $filename String - * @param $expected Integer Total image area - * @dataProvider dataGetImageArea - */ - public function testGetImageArea( $filename, $expected ) { - $file = $this->dataFile($filename, 'image/png' ); - $actual = $this->handler->getImageArea( $file, $file->getWidth(), $file->getHeight() ); - $this->assertEquals( $expected, $actual ); - } - public function dataGetImageArea() { - return array( - array( '1bit-png.png', 2500 ), - array( 'greyscale-png.png', 2500 ), - array( 'Png-native-test.png', 126000 ), - array( 'Animated_PNG_example_bouncing_beach_ball.png', 10000 ), - ); - } - - /** - * @param $metadata String Serialized metadata - * @param $expected Integer One of the class constants of PNGHandler - * @dataProvider dataIsMetadataValid - */ - public function testIsMetadataValid( $metadata, $expected ) { - $actual = $this->handler->isMetadataValid( null, $metadata ); - $this->assertEquals( $expected, $actual ); - } - public function dataIsMetadataValid() { - return array( - array( PNGHandler::BROKEN_FILE, PNGHandler::METADATA_GOOD ), - array( '', PNGHandler::METADATA_BAD ), - array( null, PNGHandler::METADATA_BAD ), - array( 'Something invalid!', PNGHandler::METADATA_BAD ), - array( 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}', PNGHandler::METADATA_GOOD ), - ); - } - - /** - * @param $filename String - * @param $expected String Serialized array - * @dataProvider dataGetMetadata - */ - public function testGetMetadata( $filename, $expected ) { - $file = $this->dataFile( $filename, 'image/png' ); - $actual = $this->handler->getMetadata( $file, "$this->filePath/$filename" ); -// $this->assertEquals( unserialize( $expected ), unserialize( $actual ) ); - $this->assertEquals( ( $expected ), ( $actual ) ); - } - public function dataGetMetadata() { - return array( - array( 'rgb-na-png.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:8;s:9:"colorType";s:10:"truecolour";s:8:"metadata";a:1:{s:15:"_MW_PNG_VERSION";i:1;}}' ), - array( 'xmp.png', 'a:6:{s:10:"frameCount";i:0;s:9:"loopCount";i:1;s:8:"duration";d:0;s:8:"bitDepth";i:1;s:9:"colorType";s:14:"index-coloured";s:8:"metadata";a:2:{s:12:"SerialNumber";s:9:"123456789";s:15:"_MW_PNG_VERSION";i:1;}}' ), - ); - } - - private function dataFile( $name, $type ) { - return new UnregisteredLocalFile( false, $this->repo, - "mwstore://localtesting/data/$name", $type ); - } -} diff --git a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php b/tests/phpunit/includes/media/SVGMetadataExtractorTest.php deleted file mode 100644 index 2116554e..00000000 --- a/tests/phpunit/includes/media/SVGMetadataExtractorTest.php +++ /dev/null @@ -1,108 +0,0 @@ -assertMetadata( $infile, $expected ); - } - - /** - * @dataProvider providerSvgFilesWithXMLMetadata - */ - function testGetXMLMetadata( $infile, $expected ) { - $r = new XMLReader(); - if( !method_exists( $r, 'readInnerXML' ) ) { - $this->markTestSkipped( 'XMLReader::readInnerXML() does not exist (libxml >2.6.20 needed).' ); - return; - } - $this->assertMetadata( $infile, $expected ); - } - - function assertMetadata( $infile, $expected ) { - try { - $data = SVGMetadataExtractor::getMetadata( $infile ); - $this->assertEquals( $expected, $data, 'SVG metadata extraction test' ); - } catch ( MWException $e ) { - if ( $expected === false ) { - $this->assertTrue( true, 'SVG metadata extracted test (expected failure)' ); - } else { - throw $e; - } - } - } - - function providerSvgFiles() { - $base = __DIR__ . '/../../data/media'; - return array( - array( - "$base/Wikimedia-logo.svg", - array( - 'width' => 1024, - 'height' => 1024, - 'originalWidth' => '1024', - 'originalHeight' => '1024', - ) - ), - array( - "$base/QA_icon.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60', - 'originalHeight' => '60', - ) - ), - array( - "$base/Gtk-media-play-ltr.svg", - array( - 'width' => 60, - 'height' => 60, - 'originalWidth' => '60.0000000', - 'originalHeight' => '60.0000000', - ) - ), - array( - "$base/Toll_Texas_1.svg", - // This file triggered bug 31719, needs entity expansion in the xmlns checks - array( - 'width' => 385, - 'height' => 385, - 'originalWidth' => '385', - 'originalHeight' => '385.0004883', - ) - ) - ); - } - - function providerSvgFilesWithXMLMetadata() { - $base = __DIR__ . '/../../data/media'; - $metadata = - ' - - image/svg+xml - - - '; - $metadata = str_replace( "\r", '', $metadata ); // Windows compat - return array( - array( - "$base/US_states_by_total_state_tax_revenue.svg", - array( - 'height' => 593, - 'metadata' => $metadata, - 'width' => 959, - 'originalWidth' => '958.69', - 'originalHeight' => '592.78998', - ) - ), - ); - } -} - diff --git a/tests/phpunit/includes/media/TiffTest.php b/tests/phpunit/includes/media/TiffTest.php deleted file mode 100644 index 4c79f66c..00000000 --- a/tests/phpunit/includes/media/TiffTest.php +++ /dev/null @@ -1,35 +0,0 @@ -showExif = $wgShowEXIF; - $wgShowEXIF = true; - $this->filePath = __DIR__ . '/../../data/media/'; - $this->handler = new TiffHandler; - } - - public function tearDown() { - global $wgShowEXIF; - $wgShowEXIF = $this->showExif; - } - - public function testInvalidFile() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } - $res = $this->handler->getMetadata( null, $this->filePath . 'README' ); - $this->assertEquals( ExifBitmapHandler::BROKEN_FILE, $res ); - } - - public function testTiffMetadataExtraction() { - if ( !wfDl( 'exif' ) ) { - $this->markTestIncomplete( "This test needs the exif extension." ); - } - $res = $this->handler->getMetadata( null, $this->filePath . 'test.tiff' ); - $expected = 'a:16:{s:10:"ImageWidth";i:20;s:11:"ImageLength";i:20;s:13:"BitsPerSample";a:3:{i:0;i:8;i:1;i:8;i:2;i:8;}s:11:"Compression";i:5;s:25:"PhotometricInterpretation";i:2;s:16:"ImageDescription";s:17:"Created with GIMP";s:12:"StripOffsets";i:8;s:11:"Orientation";i:1;s:15:"SamplesPerPixel";i:3;s:12:"RowsPerStrip";i:64;s:15:"StripByteCounts";i:238;s:11:"XResolution";s:19:"1207959552/16777216";s:11:"YResolution";s:19:"1207959552/16777216";s:19:"PlanarConfiguration";i:1;s:14:"ResolutionUnit";i:2;s:22:"MEDIAWIKI_EXIF_VERSION";i:2;}'; - // Re-unserialize in case there are subtle differences between how versions - // of php serialize stuff. - $this->assertEquals( unserialize( $expected ), unserialize( $res ) ); - } -} diff --git a/tests/phpunit/includes/media/XMPTest.php b/tests/phpunit/includes/media/XMPTest.php deleted file mode 100644 index 8198d3b0..00000000 --- a/tests/phpunit/includes/media/XMPTest.php +++ /dev/null @@ -1,158 +0,0 @@ -markTestSkipped( 'Requires libxml to do XMP parsing' ); - } - } - - /** - * Put XMP in, compare what comes out... - * - * @param $xmp String the actual xml data. - * @param $expected Array expected result of parsing the xmp. - * @param $info String Short sentence on what's being tested. - * - * @dataProvider dataXMPParse - */ - public function testXMPParse( $xmp, $expected, $info ) { - if ( !is_string( $xmp ) || !is_array( $expected ) ) { - throw new Exception( "Invalid data provided to " . __METHOD__ ); - } - $reader = new XMPReader; - $reader->parse( $xmp ); - $this->assertEquals( $expected, $reader->getResults(), $info, 0.0000000001 ); - } - - public function dataXMPParse() { - $xmpPath = __DIR__ . '/../../data/xmp/' ; - $data = array(); - - // $xmpFiles format: array of arrays with first arg file base name, - // with the actual file having .xmp on the end for the xmp - // and .result.php on the end for a php file containing the result - // array. Second argument is some info on what's being tested. - $xmpFiles = array( - array( '1', 'parseType=Resource test' ), - array( '2', 'Structure with mixed attribute and element props' ), - array( '3', 'Extra qualifiers (that should be ignored)' ), - array( '3-invalid', 'Test ignoring qualifiers that look like normal props' ), - array( '4', 'Flash as qualifier' ), - array( '5', 'Flash as qualifier 2' ), - array( '6', 'Multiple rdf:Description' ), - array( '7', 'Generic test of several property types' ), - array( 'flash', 'Test of Flash property' ), - array( 'invalid-child-not-struct', 'Test child props not in struct or ignored' ), - array( 'no-recognized-props', 'Test namespace and no recognized props' ), - array( 'no-namespace', 'Test non-namespaced attributes are ignored' ), - array( 'bag-for-seq', "Allow bag's instead of seq's. (bug 27105)" ), - array( 'utf16BE', 'UTF-16BE encoding' ), - array( 'utf16LE', 'UTF-16LE encoding' ), - array( 'utf32BE', 'UTF-32BE encoding' ), - array( 'utf32LE', 'UTF-32LE encoding' ), - array( 'xmpExt', 'Extended XMP missing second part' ), - array( 'gps', 'Handling of exif GPS parameters in XMP' ), - ); - foreach( $xmpFiles as $file ) { - $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' ); - // I'm not sure if this is the best way to handle getting the - // result array, but it seems kind of big to put directly in the test - // file. - $result = null; - include( $xmpPath . $file[0] . '.result.php' ); - $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] ); - } - return $data; - } - - /** Test ExtendedXMP block support. (Used when the XMP has to be split - * over multiple jpeg segments, due to 64k size limit on jpeg segments. - * - * @todo This is based on what the standard says. Need to find a real - * world example file to double check the support for this is right. - */ - function testExtendedXMP() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - 'FNumber' => '2/10', - ) - ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * This test has an extended XMP block with a wrong guid (md5sum) - * and thus should only return the StandardXMP, not the ExtendedXMP. - */ - function testExtendedXMPWithWrongGUID() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B9'; // Note last digit. - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 0 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } - /** - * Have a high offset to simulate a missing packet, - * which should cause it to ignore the ExtendedXMP packet. - */ - function testExtendedXMPMissingPacket() { - $xmpPath = __DIR__ . '/../../data/xmp/'; - $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' ); - $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' ); - - $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp - $length = pack( 'N', strlen( $extendedXMP ) ); - $offset = pack( 'N', 2048 ); - $extendedPacket = $md5sum . $length . $offset . $extendedXMP; - - $reader = new XMPReader(); - $reader->parse( $standardXMP ); - $reader->parseExtended( $extendedPacket ); - $actual = $reader->getResults(); - - $expected = array( 'xmp-exif' => - array( - 'DigitalZoomRatio' => '0/10', - 'Flash' => 9, - ) - ); - - $this->assertEquals( $expected, $actual ); - } - -} diff --git a/tests/phpunit/includes/media/XMPValidateTest.php b/tests/phpunit/includes/media/XMPValidateTest.php deleted file mode 100644 index e2bb8d8d..00000000 --- a/tests/phpunit/includes/media/XMPValidateTest.php +++ /dev/null @@ -1,47 +0,0 @@ -assertEquals( $expected, $value ); - } - - function providerDate() { - /* For reference valid date formats are: - * YYYY - * YYYY-MM - * YYYY-MM-DD - * YYYY-MM-DDThh:mmTZD - * YYYY-MM-DDThh:mm:ssTZD - * YYYY-MM-DDThh:mm:ss.sTZD - * (Time zone is optional) - */ - return array( - array( '1992', '1992' ), - array( '1992-04', '1992:04' ), - array( '1992-02-01', '1992:02:01' ), - array( '2011-09-29', '2011:09:29' ), - array( '1982-12-15T20:12', '1982:12:15 20:12' ), - array( '1982-12-15T20:12Z', '1982:12:15 20:12' ), - array( '1982-12-15T20:12+02:30', '1982:12:15 22:42' ), - array( '1982-12-15T01:12-02:30', '1982:12:14 22:42' ), - array( '1982-12-15T20:12:11', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11Z', '1982:12:15 20:12:11' ), - array( '1982-12-15T20:12:11+01:10', '1982:12:15 21:22:11' ), - array( '2045-12-15T20:12:11', '2045:12:15 20:12:11' ), - array( '1867-06-01T15:00:00', '1867:06:01 15:00:00' ), - /* some invalid ones */ - array( '2001--12', null ), - array( '2001-5-12', null ), - array( '2001-5-12TZ', null ), - array( '2001-05-12T15', null ), - array( '2001-12T15:13', null ), - ); - - } - -} diff --git a/tests/phpunit/includes/mobile/DeviceDetectionTest.php b/tests/phpunit/includes/mobile/DeviceDetectionTest.php deleted file mode 100644 index 0e156532..00000000 --- a/tests/phpunit/includes/mobile/DeviceDetectionTest.php +++ /dev/null @@ -1,40 +0,0 @@ -assertEquals( $format, $detector->detectFormatName( $userAgent ) ); - } - - public function provideTestFormatName() { - return array( - array( 'android', 'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17' ), - array( 'iphone2', 'Mozilla/5.0 (ipod: U;CPU iPhone OS 2_2 like Mac OS X: es_es) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3' ), - array( 'iphone', 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3B48b Safari/419.3' ), - array( 'nokia', 'Mozilla/5.0 (SymbianOS/9.1; U; [en]; SymbianOS/91 Series60/3.0) AppleWebKit/413 (KHTML, like Gecko) Safari/413' ), - array( 'palm_pre', 'Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0' ), - array( 'wii', 'Opera/9.00 (Nintendo Wii; U; ; 1309-9; en)' ), - array( 'operamini', 'Opera/9.50 (J2ME/MIDP; Opera Mini/4.0.10031/298; U; en)' ), - array( 'operamobile', 'Opera/9.51 Beta (Microsoft Windows; PPC; Opera Mobi/1718; U; en)' ), - array( 'kindle', 'Mozilla/4.0 (compatible; Linux 2.6.10) NetFront/3.3 Kindle/1.0 (screen 600x800)' ), - array( 'kindle2', 'Mozilla/4.0 (compatible; Linux 2.6.22) NetFront/3.4 Kindle/2.0 (screen 824x1200; rotate)' ), - array( 'capable', 'Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1' ), - array( 'netfront', 'Mozilla/4.08 (Windows; Mobile Content Viewer/1.0) NetFront/3.2' ), - array( 'wap2', 'SonyEricssonK608i/R2L/SN356841000828910 Browser/SEMC-Browser/4.2 Profile/MIDP-2.0 Configuration/CLDC-1.1' ), - array( 'wap2', 'NokiaN73-2/3.0-630.0.2 Series60/3.0 Profile/MIDP-2.0 Configuration/CLDC-1.1' ), - array( 'psp', 'Mozilla/4.0 (PSP (PlayStation Portable); 2.00)' ), - array( 'ps3', 'Mozilla/5.0 (PLAYSTATION 3; 1.00)' ), - array( 'ie', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)' ), - array( 'ie', 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)' ), - array( 'blackberry', 'BlackBerry9300/5.0.0.716 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/133' ), - array( 'blackberry-lt5', 'BlackBerry7250/4.0.0 Profile/MIDP-2.0 Configuration/CLDC-1.1' ), - ); - } -} diff --git a/tests/phpunit/includes/normal/CleanUpTest.php b/tests/phpunit/includes/normal/CleanUpTest.php deleted file mode 100644 index d5ad18d8..00000000 --- a/tests/phpunit/includes/normal/CleanUpTest.php +++ /dev/null @@ -1,382 +0,0 @@ - - * http://www.mediawiki.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * http://www.gnu.org/copyleft/gpl.html - * - * @file - */ - -/** - * Additional tests for UtfNormal::cleanUp() function, inclusion - * regression checks for known problems. - * Requires PHPUnit. - * - * @ingroup UtfNormal - */ -class CleanUpTest extends MediaWikiTestCase { - /** @todo document */ - function testAscii() { - $text = 'This is plain ASCII text.'; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - function testNull() { - $text = "a \x00 null"; - $expect = "a \xef\xbf\xbd null"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testLatin() { - $text = "L'\xc3\xa9cole"; - $this->assertEquals( $text, UtfNormal::cleanUp( $text ) ); - } - - /** @todo document */ - function testLatinNormal() { - $text = "L'e\xcc\x81cole"; - $expect = "L'\xc3\xa9cole"; - $this->assertEquals( $expect, UtfNormal::cleanUp( $text ) ); - } - - /** - * This test is *very* expensive! - * @todo document - */ - function XtestAllChars() { - $rep = UTF8_REPLACEMENT; - for( $i = 0x0; $i < UNICODE_MAX; $i++ ) { - $char = codepointToUtf8( $i ); - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%04X", $i ); - if( $i % 0x1000 == 0 ) echo "U+$x\n"; - if( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ($i > 0x001f && $i < UNICODE_SURROGATE_FIRST) || - ($i > UNICODE_SURROGATE_LAST && $i < 0xfffe ) || - ($i > 0xffff && $i <= UNICODE_MAX ) ) { - if( isset( UtfNormal::$utfCanonicalComp[$char] ) || isset( UtfNormal::$utfCanonicalDecomp[$char] ) ) { - $comp = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $comp ), - bin2hex( $clean ), - "U+$x should be decomposed" ); - } else { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "U+$x should be intact" ); - } - } else { - $this->assertEquals( bin2hex( $rep ), bin2hex( $clean ), $x ); - } - } - } - - /** @todo document */ - function testAllBytes() { - $this->doTestBytes( '', '' ); - $this->doTestBytes( 'x', '' ); - $this->doTestBytes( '', 'x' ); - $this->doTestBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestBytes( $head, $tail ) { - for( $i = 0x0; $i < 256; $i++ ) { - $char = $head . chr( $i ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X", $i ); - if( $i == 0x0009 || - $i == 0x000a || - $i == 0x000d || - ($i > 0x001f && $i < 0x80) ) { - $this->assertEquals( - bin2hex( $char ), - bin2hex( $clean ), - "ASCII byte $x should be intact" ); - if( $char != $clean ) return; - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden byte $x should be rejected" ); - if( $norm != $clean ) return; - } - } - } - - /** @todo document */ - function testDoubleBytes() { - $this->doTestDoubleBytes( '', '' ); - $this->doTestDoubleBytes( 'x', '' ); - $this->doTestDoubleBytes( '', 'x' ); - $this->doTestDoubleBytes( 'x', 'x' ); - } - - /** - * @todo document - */ - function doTestDoubleBytes( $head, $tail ) { - for( $first = 0xc0; $first < 0x100; $first+=2 ) { - for( $second = 0x80; $second < 0x100; $second+=2 ) { - $char = $head . chr( $first ) . chr( $second ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X", $first, $second ); - if( $first > 0xc1 && - $first < 0xe0 && - $second < 0xc0 ) { - $norm = UtfNormal::NFC( $char ); - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Pair $x should be intact" ); - if( $norm != $clean ) return; - } elseif( $first > 0xfd || $second > 0xbf ) { - # fe and ff are not legal head bytes -- expect two replacement chars - $norm = $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if( $norm != $clean ) return; - } else { - $norm = $head . UTF8_REPLACEMENT . $tail; - $this->assertEquals( - bin2hex( $norm ), - bin2hex( $clean ), - "Forbidden pair $x should be rejected" ); - if( $norm != $clean ) return; - } - } - } - } - - /** @todo document */ - function testTripleBytes() { - $this->doTestTripleBytes( '', '' ); - $this->doTestTripleBytes( 'x', '' ); - $this->doTestTripleBytes( '', 'x' ); - $this->doTestTripleBytes( 'x', 'x' ); - } - - /** @todo document */ - function doTestTripleBytes( $head, $tail ) { - for( $first = 0xc0; $first < 0x100; $first+=2 ) { - for( $second = 0x80; $second < 0x100; $second+=2 ) { - #for( $third = 0x80; $third < 0x100; $third++ ) { - for( $third = 0x80; $third < 0x81; $third++ ) { - $char = $head . chr( $first ) . chr( $second ) . chr( $third ) . $tail; - $clean = UtfNormal::cleanUp( $char ); - $x = sprintf( "%02X,%02X,%02X", $first, $second, $third ); - if( $first >= 0xe0 && - $first < 0xf0 && - $second < 0xc0 && - $third < 0xc0 ) { - if( $first == 0xe0 && $second < 0xa0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Overlong triplet $x should be rejected" ); - } elseif( $first == 0xed && - ( chr( $first ) . chr( $second ) . chr( $third )) >= UTF8_SURROGATE_FIRST ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Surrogate triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $char ) ), - bin2hex( $clean ), - "Triplet $x should be intact" ); - } - } elseif( $first > 0xc1 && $first < 0xe0 && $second < 0xc0 ) { - $this->assertEquals( - bin2hex( UtfNormal::NFC( $head . chr( $first ) . chr( $second ) ) . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Valid 2-byte $x + broken tail" ); - } elseif( $second > 0xc1 && $second < 0xe0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UtfNormal::NFC( chr( $second ) . chr( $third ) . $tail ) ), - bin2hex( $clean ), - "Broken head + valid 2-byte $x" ); - } elseif( ( $first > 0xfd || $second > 0xfd ) && - ( ( $second > 0xbf && $third > 0xbf ) || - ( $second < 0xc0 && $third < 0xc0 ) || - ( $second > 0xfd ) || - ( $third > 0xfd ) ) ) { - # fe and ff are not legal head bytes -- expect three replacement chars - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } elseif( $first > 0xc2 && $second < 0xc0 && $third < 0xc0 ) { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } else { - $this->assertEquals( - bin2hex( $head . UTF8_REPLACEMENT . UTF8_REPLACEMENT . $tail ), - bin2hex( $clean ), - "Forbidden triplet $x should be rejected" ); - } - } - } - } - } - - /** @todo document */ - function testChunkRegression() { - # Check for regression against a chunking bug - $text = "\x46\x55\xb8" . - "\xdc\x96" . - "\xee" . - "\xe7" . - "\x44" . - "\xaa" . - "\x2f\x25"; - $expect = "\x46\x55\xef\xbf\xbd" . - "\xdc\x96" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x44" . - "\xef\xbf\xbd" . - "\x2f\x25"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testInterposeRegression() { - $text = "\x4e\x30" . - "\xb1" . # bad tail - "\x3a" . - "\x92" . # bad tail - "\x62\x3a" . - "\x84" . # bad tail - "\x43" . - "\xc6" . # bad head - "\x3f" . - "\x92" . # bad tail - "\xad" . # bad tail - "\x7d" . - "\xd9\x95"; - - $expect = "\x4e\x30" . - "\xef\xbf\xbd" . - "\x3a" . - "\xef\xbf\xbd" . - "\x62\x3a" . - "\xef\xbf\xbd" . - "\x43" . - "\xef\xbf\xbd" . - "\x3f" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x7d" . - "\xd9\x95"; - - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testOverlongRegression() { - $text = "\x67" . - "\x1a" . # forbidden ascii - "\xea" . # bad head - "\xc1\xa6" . # overlong sequence - "\xad" . # bad tail - "\x1c" . # forbidden ascii - "\xb0" . # bad tail - "\x3c" . - "\x9e"; # bad tail - $expect = "\x67" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x3c" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testSurrogateRegression() { - $text = "\xed\xb4\x96" . # surrogate 0xDD16 - "\x83" . # bad tail - "\xb4" . # bad tail - "\xac"; # bad head - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testBomRegression() { - $text = "\xef\xbf\xbe" . # U+FFFE, illegal char - "\xb2" . # bad tail - "\xef" . # bad head - "\x59"; - $expect = "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\xef\xbf\xbd" . - "\x59"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testForbiddenRegression() { - $text = "\xef\xbf\xbf"; # U+FFFF, illegal char - $expect = "\xef\xbf\xbd"; - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } - - /** @todo document */ - function testHangulRegression() { - $text = "\xed\x9c\xaf" . # Hangul char - "\xe1\x87\x81"; # followed by another final jamo - $expect = $text; # Should *not* change. - $this->assertEquals( - bin2hex( $expect ), - bin2hex( UtfNormal::cleanUp( $text ) ) ); - } -} diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php deleted file mode 100644 index 31645313..00000000 --- a/tests/phpunit/includes/parser/MagicVariableTest.php +++ /dev/null @@ -1,201 +0,0 @@ -testParser = new Parser(); - $this->testParser->Options( new ParserOptions() ); - - # initialize parser output - $this->testParser->clearState(); - - # Needs a title to do magic word stuff - $title = Title::newFromText( 'Tests' ); - $title->mRedirect = false; # Else it needs a db connection just to check if it's a redirect (when deciding the page language) - - $this->testParser->setTitle( $title ); - } - - /** destroy parser (TODO: is it really neded?)*/ - function tearDown() { - unset( $this->testParser ); - } - - ############### TESTS ############################################# - # @todo FIXME: - # - those got copy pasted, we can probably make them cleaner - # - tests are lacking useful messages - - # day - - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdayIsUnPadded( $day ) { - $this->assertUnPadded( 'currentday', $day ); - } - /** @dataProvider MediaWikiProvide::Days */ - function testCurrentdaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'currentday2', $day ); - } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldayIsUnPadded( $day ) { - $this->assertUnPadded( 'localday', $day ); - } - /** @dataProvider MediaWikiProvide::Days */ - function testLocaldaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'localday2', $day ); - } - - # month - - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'currentmonth', $month ); - } - /** @dataProvider MediaWikiProvide::Months */ - function testCurrentmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'currentmonth1', $month ); - } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'localmonth', $month ); - } - /** @dataProvider MediaWikiProvide::Months */ - function testLocalmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'localmonth1', $month ); - } - - - # revision day - - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondayIsUnPadded( $day ) { - $this->assertUnPadded( 'revisionday', $day ); - } - /** @dataProvider MediaWikiProvide::Days */ - function testRevisiondaytwoIsZeroPadded( $day ) { - $this->assertZeroPadded( 'revisionday2', $day ); - } - - # revision month - - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthIsZeroPadded( $month ) { - $this->assertZeroPadded( 'revisionmonth', $month ); - } - /** @dataProvider MediaWikiProvide::Months */ - function testRevisionmonthoneIsUnPadded( $month ) { - $this->assertUnPadded( 'revisionmonth1', $month ); - } - - /** - * Rough tests for {{SERVERNAME}} magic word - * Bug 31176 - */ - function testServernameFromDifferentProtocols() { - global $wgServer; - $saved_wgServer= $wgServer; - - $wgServer = 'http://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = 'https://localhost/'; - $this->assertMagic( 'localhost', 'servername' ); - $wgServer = '//localhost/'; # bug 31176 - $this->assertMagic( 'localhost', 'servername' ); - - $wgServer = $saved_wgServer; - } - - ############### HELPERS ############################################ - - /** assertion helper expecting a magic output which is zero padded */ - PUBLIC function assertZeroPadded( $magic, $value ) { - $this->assertMagicPadding( $magic, $value, '%02d' ); - } - - /** assertion helper expecting a magic output which is unpadded */ - PUBLIC function assertUnPadded( $magic, $value ) { - $this->assertMagicPadding( $magic, $value, '%d' ); - } - - /** - * Main assertion helper for magic variables padding - * @param $magic string Magic variable name - * @param $value mixed Month or day - * @param $format string sprintf format for $value - */ - private function assertMagicPadding( $magic, $value, $format ) { - # Initialize parser timestamp as year 2010 at 12h34 56s. - # month and day are given by the caller ($value). Month < 12! - if( $value > 12 ) { $month = $value % 12; } - else { $month = $value; } - - $this->setParserTS( - sprintf( '2010%02d%02d123456', $month, $value ) - ); - - # please keep the following commented line of code. It helps debugging. - //print "\nDEBUG (value $value):" . sprintf( '2010%02d%02d123456', $value, $value ) . "\n"; - - # format expectation and test it - $expected = sprintf( $format, $value ); - $this->assertMagic( $expected, $magic ); - } - - /** helper to set the parser timestamp and revision timestamp */ - private function setParserTS( $ts ) { - $this->testParser->Options()->setTimestamp( $ts ); - $this->testParser->mRevisionTimestamp = $ts; - } - - /** - * Assertion helper to test a magic variable output - */ - private function assertMagic( $expected, $magic ) { - if( in_array( $magic, $this->expectedAsInteger ) ) { - $expected = (int) $expected; - } - - # Generate a message for the assertion - $msg = sprintf( "Magic %s should be <%s:%s>", - $magic, - $expected, - gettype( $expected ) - ); - - $this->assertSame( - $expected, - $this->testParser->getVariableValue( $magic ), - $msg - ); - } -} diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php deleted file mode 100644 index 6a6fded1..00000000 --- a/tests/phpunit/includes/parser/MediaWikiParserTest.php +++ /dev/null @@ -1,36 +0,0 @@ - "\\'", '\\' => '\\\\' ) ) . "'; } " ); - - $parserTester = new $className( $testsName ); - $suite->addTestSuite( new ReflectionClass ( $parserTester ) ); - } - - - return $suite; - } -} diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php deleted file mode 100644 index 69a96e66..00000000 --- a/tests/phpunit/includes/parser/NewParserTest.php +++ /dev/null @@ -1,895 +0,0 @@ -getCliArg( 'regex=' ) ) { - $this->regex = $this->getCliArg( 'regex=' ); - } else { - # Matches anything - $this->regex = ''; - } - - $this->keepUploads = $this->getCliArg( 'keep-uploads' ); - - $tmpGlobals = array(); - - $tmpGlobals['wgScript'] = '/index.php'; - $tmpGlobals['wgScriptPath'] = '/'; - $tmpGlobals['wgArticlePath'] = '/wiki/$1'; - $tmpGlobals['wgStyleSheetPath'] = '/skins'; - $tmpGlobals['wgStylePath'] = '/skins'; - $tmpGlobals['wgThumbnailScriptPath'] = false; - $tmpGlobals['wgLocalFileRepo'] = array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => 'local-backend' - ); - $tmpGlobals['wgForeignFileRepos'] = array(); - $tmpGlobals['wgEnableParserCache'] = false; - $tmpGlobals['wgHooks'] = $wgHooks; - $tmpGlobals['wgDeferredUpdateList'] = array(); - $tmpGlobals['wgMemc'] = wfGetMainCache(); - $tmpGlobals['messageMemc'] = wfGetMessageCacheStorage(); - $tmpGlobals['parserMemc'] = wfGetParserCacheStorage(); - - // $tmpGlobals['wgContLang'] = new StubContLang; - $tmpGlobals['wgUser'] = new User; - $context = new RequestContext(); - $tmpGlobals['wgLang'] = $context->getLanguage(); - $tmpGlobals['wgOut'] = $context->getOutput(); - $tmpGlobals['wgParser'] = new StubObject( 'wgParser', $GLOBALS['wgParserConf']['class'], array( $GLOBALS['wgParserConf'] ) ); - $tmpGlobals['wgRequest'] = $context->getRequest(); - - if ( $GLOBALS['wgStyleDirectory'] === false ) { - $tmpGlobals['wgStyleDirectory'] = "$IP/skins"; - } - - - foreach ( $tmpGlobals as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedInitialGlobals[$var] = $GLOBALS[$var]; - } - - $GLOBALS[$var] = $val; - } - - $this->savedWeirdGlobals['mw_namespace_protection'] = $wgNamespaceProtection[NS_MEDIAWIKI]; - $this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image']; - $this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk']; - - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - } - - public function tearDown() { - foreach ( $this->savedInitialGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - - global $wgNamespaceProtection, $wgNamespaceAliases; - - $wgNamespaceProtection[NS_MEDIAWIKI] = $this->savedWeirdGlobals['mw_namespace_protection']; - $wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias']; - $wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias']; - - // Restore backends - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - } - - function addDBData() { - $this->tablesUsed[] = 'site_stats'; - $this->tablesUsed[] = 'interwiki'; - # disabled for performance - #$this->tablesUsed[] = 'image'; - - # Hack: insert a few Wikipedia in-project interwiki prefixes, - # for testing inter-language links - $this->db->insert( 'interwiki', array( - array( 'iw_prefix' => 'wikipedia', - 'iw_url' => 'http://en.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'meatball', - 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 0 ), - array( 'iw_prefix' => 'zh', - 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'es', - 'iw_url' => 'http://es.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'fr', - 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - array( 'iw_prefix' => 'ru', - 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', - 'iw_api' => '', - 'iw_wikiid' => '', - 'iw_local' => 1 ), - /** - * @todo Fixme! Why are we inserting duplicate data here? Shouldn't - * need this IGNORE or shouldn't need the insert at all. - */ - ), __METHOD__, array( 'IGNORE' ) - ); - - - # Update certain things in site_stats - $this->db->insert( 'site_stats', - array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ), - __METHOD__ - ); - - # Reinitialise the LocalisationCache to match the database state - Language::getLocalisationCache()->unloadAll(); - - # Clear the message cache - MessageCache::singleton()->clear(); - - $user = User::newFromId( 0 ); - LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision - - # Upload DB table entries for files. - # We will upload the actual files later. Note that if anything causes LocalFile::load() - # to be triggered before then, it will break via maybeUpgrade() setting the fileExists - # member to false and storing it in cache. - $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); - if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { - $image->recordUpload2( - '', // archive name - 'Upload of some lame file', - 'Some lame file', - array( - 'size' => 12345, - 'width' => 1941, - 'height' => 220, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), - 'fileExists' => true ), - $this->db->timestamp( '20010115123500' ), $user - ); - } - - # This image will be blacklisted in [[MediaWiki:Bad image list]] - $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) ); - if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) { - $image->recordUpload2( - '', // archive name - 'zomgnotcensored', - 'Borderline image', - array( - 'size' => 12345, - 'width' => 320, - 'height' => 240, - 'bits' => 24, - 'media_type' => MEDIATYPE_BITMAP, - 'mime' => 'image/jpeg', - 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), - 'fileExists' => true ), - $this->db->timestamp( '20010115123500' ), $user - ); - } - } - - - - - //ParserTest setup/teardown functions - - /** - * Set up the global variables for a consistent environment for each test. - * Ideally this should replace the global configuration entirely. - */ - protected function setupGlobals( $opts = '', $config = '' ) { - global $wgFileBackends; - # Find out values for some special options. - $lang = - self::getOptionValue( 'language', $opts, 'en' ); - $variant = - self::getOptionValue( 'variant', $opts, false ); - $maxtoclevel = - self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); - $linkHolderBatchSize = - self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); - - $uploadDir = $this->getUploadDir(); - if ( $this->getCliArg( 'use-filebackend=' ) ) { - if ( self::$backendToUse ) { - $backend = self::$backendToUse; - } else { - $name = $this->getCliArg( 'use-filebackend=' ); - $useConfig = array(); - foreach ( $wgFileBackends as $conf ) { - if ( $conf['name'] == $name ) { - $useConfig = $conf; - } - } - $useConfig['name'] = 'local-backend'; // swap name - $class = $conf['class']; - self::$backendToUse = new $class( $useConfig ); - $backend = self::$backendToUse; - } - } else { - $backend = new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'nullLockManager', - 'containerPaths' => array( - 'local-public' => "$uploadDir", - 'local-thumb' => "$uploadDir/thumb", - ) - ) ); - } - - $settings = array( - 'wgServer' => 'http://Britney-Spears', - 'wgScript' => '/index.php', - 'wgScriptPath' => '/', - 'wgArticlePath' => '/wiki/$1', - 'wgExtensionAssetsPath' => '/extensions', - 'wgActionPaths' => array(), - 'wgLocalFileRepo' => array( - 'class' => 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => $backend - ), - 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), - 'wgStylePath' => '/skins', - 'wgStyleSheetPath' => '/skins', - 'wgSitename' => 'MediaWiki', - 'wgLanguageCode' => $lang, - 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', - 'wgRawHtml' => isset( $opts['rawhtml'] ), - 'wgLang' => null, - 'wgContLang' => null, - 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ), - 'wgMaxTocLevel' => $maxtoclevel, - 'wgCapitalLinks' => true, - 'wgNoFollowLinks' => true, - 'wgNoFollowDomainExceptions' => array(), - 'wgThumbnailScriptPath' => false, - 'wgUseImageResize' => false, - 'wgUseTeX' => isset( $opts['math'] ), - 'wgMathDirectory' => $uploadDir . '/math', - 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, - 'wgUseTidy' => false, - 'wgDefaultLanguageVariant' => $variant, - 'wgVariantArticlePath' => false, - 'wgGroupPermissions' => array( '*' => array( - 'createaccount' => true, - 'read' => true, - 'edit' => true, - 'createpage' => true, - 'createtalk' => true, - ) ), - 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ), - 'wgDefaultExternalStore' => array(), - 'wgForeignFileRepos' => array(), - 'wgLinkHolderBatchSize' => $linkHolderBatchSize, - 'wgExperimentalHtmlIds' => false, - 'wgExternalLinkTarget' => false, - 'wgAlwaysUseTidy' => false, - 'wgHtml5' => true, - 'wgWellFormedXml' => true, - 'wgAllowMicrodataAttributes' => true, - 'wgAdaptiveMessageCache' => true, - 'wgUseDatabaseMessages' => true, - ); - - if ( $config ) { - $configLines = explode( "\n", $config ); - - foreach ( $configLines as $line ) { - list( $var, $value ) = explode( '=', $line, 2 ); - - $settings[$var] = eval( "return $value;" ); //??? - } - } - - $this->savedGlobals = array(); - - /** @since 1.20 */ - wfRunHooks( 'ParserTestGlobals', array( &$settings ) ); - - foreach ( $settings as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedGlobals[$var] = $GLOBALS[$var]; - } - - $GLOBALS[$var] = $val; - } - - $langObj = Language::factory( $lang ); - $GLOBALS['wgContLang'] = $langObj; - $context = new RequestContext(); - $GLOBALS['wgLang'] = $context->getLanguage(); - - $GLOBALS['wgMemc'] = new EmptyBagOStuff; - $GLOBALS['wgOut'] = $context->getOutput(); - $GLOBALS['wgUser'] = $context->getUser(); - - global $wgHooks; - - $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; - $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; - - MagicWord::clearCache(); - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - - # Create dummy files in storage - $this->setupUploads(); - - # Publish the articles after we have the final language set - $this->publishTestArticles(); - - # The entries saved into RepoGroup cache with previous globals will be wrong. - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - MessageCache::destroyInstance(); - - return $context; - } - - /** - * Get an FS upload directory (only applies to FSFileBackend) - * - * @return String: the directory - */ - protected function getUploadDir() { - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - // wfDebug( "Creating upload directory $dir\n" ); - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - return $dir; - } - - return $dir; - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - protected function setupUploads() { - global $IP; - - $base = $this->getBaseDir(); - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - $backend->prepare( array( 'dir' => "$base/local-public/3/3a" ) ); - $backend->store( array( - 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/3/3a/Foobar.jpg" - ) ); - $backend->prepare( array( 'dir' => "$base/local-public/0/09" ) ); - $backend->store( array( - 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/0/09/Bad.jpg" - ) ); - } - - /** - * Restore default values and perform any necessary clean-up - * after each test runs. - */ - protected function teardownGlobals() { - $this->teardownUploads(); - - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - - RepoGroup::destroySingleton(); - LinkCache::singleton()->clear(); - } - - /** - * Remove the dummy uploads directory - */ - private function teardownUploads() { - if ( $this->keepUploads ) { - return; - } - - $base = $this->getBaseDir(); - // delete the files first, then the dirs. - self::deleteFiles( - array ( - "$base/local-public/3/3a/Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$base/local-thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$base/local-public/0/09/Bad.jpg", - "$base/local-thumb/0/09/Bad.jpg", - - "$base/local-public/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - $backend = RepoGroup::singleton()->getLocalRepo()->getBackend(); - foreach ( $files as $file ) { - $backend->delete( array( 'src' => $file ), array( 'force' => 1 ) ); - } - foreach ( $files as $file ) { - $tmp = $file; - while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) { - if ( !$backend->clean( array( 'dir' => $tmp ) )->isOK() ) { - break; - } - } - } - } - - protected function getBaseDir() { - return 'mwstore://local-backend'; - } - - public function parserTestProvider() { - if ( $this->file === false ) { - global $wgParserTestFiles; - $this->file = $wgParserTestFiles[0]; - } - return new TestFileIterator( $this->file, $this ); - } - - /** - * Set the file from whose tests will be run by this instance - */ - public function setParserTestFile( $filename ) { - $this->file = $filename; - } - - /** - * @group medium - * @dataProvider parserTestProvider - */ - public function testParserTest( $desc, $input, $result, $opts, $config ) { - if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) { - $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions" - //$this->markTestSkipped( 'Filtered out by the user' ); - return; - } - - wfDebug( "Running parser test: $desc\n" ); - - $opts = $this->parseOptions( $opts ); - $context = $this->setupGlobals( $opts, $config ); - - $user = $context->getUser(); - $options = ParserOptions::newFromContext( $context ); - - if ( isset( $opts['title'] ) ) { - $titleText = $opts['title']; - } - else { - $titleText = 'Parser test'; - } - - $local = isset( $opts['local'] ); - $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null; - $parser = $this->getParser( $preprocessor ); - - $title = Title::newFromText( $titleText ); - - if ( isset( $opts['pst'] ) ) { - $out = $parser->preSaveTransform( $input, $title, $user, $options ); - } elseif ( isset( $opts['msg'] ) ) { - $out = $parser->transformMsg( $input, $options, $title ); - } elseif ( isset( $opts['section'] ) ) { - $section = $opts['section']; - $out = $parser->getSection( $input, $section ); - } elseif ( isset( $opts['replace'] ) ) { - $section = $opts['replace'][0]; - $replace = $opts['replace'][1]; - $out = $parser->replaceSection( $input, $section, $replace ); - } elseif ( isset( $opts['comment'] ) ) { - $out = Linker::formatComment( $input, $title, $local ); - } elseif ( isset( $opts['preload'] ) ) { - $out = $parser->getpreloadText( $input, $title, $options ); - } else { - $output = $parser->parse( $input, $title, $options, true, true, 1337 ); - $out = $output->getText(); - - if ( isset( $opts['showtitle'] ) ) { - if ( $output->getTitleText() ) { - $title = $output->getTitleText(); - } - - $out = "$title\n$out"; - } - - if ( isset( $opts['ill'] ) ) { - $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); - } elseif ( isset( $opts['cat'] ) ) { - $outputPage = $context->getOutput(); - $outputPage->addCategoryLinks( $output->getCategories() ); - $cats = $outputPage->getCategoryLinks(); - - if ( isset( $cats['normal'] ) ) { - $out = $this->tidy( implode( ' ', $cats['normal'] ) ); - } else { - $out = ''; - } - } - $parser->mPreprocessor = null; - - $result = $this->tidy( $result ); - } - - $this->teardownGlobals(); - - $this->assertEquals( $result, $out, $desc ); - } - - /** - * Run a fuzz test series - * Draw input from a set of test files - * - * @todo fixme Needs some work to not eat memory until the world explodes - * - * @group ParserFuzz - */ - function testFuzzTests() { - global $wgParserTestFiles; - - $files = $wgParserTestFiles; - - if( $this->getCliArg( 'file=' ) ) { - $files = array( $this->getCliArg( 'file=' ) ); - } - - $dict = $this->getFuzzInput( $files ); - $dictSize = strlen( $dict ); - $logMaxLength = log( $this->maxFuzzTestLength ); - - ini_set( 'memory_limit', $this->memoryLimit * 1048576 ); - - $user = new User; - $opts = ParserOptions::newFromUser( $user ); - $title = Title::makeTitle( NS_MAIN, 'Parser_test' ); - - $id = 1; - - while ( true ) { - - // Generate test input - mt_srand( ++$this->fuzzSeed ); - $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); - $input = ''; - - while ( strlen( $input ) < $totalLength ) { - $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; - $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); - $offset = mt_rand( 0, $dictSize - $hairLength ); - $input .= substr( $dict, $offset, $hairLength ); - } - - $this->setupGlobals(); - $parser = $this->getParser(); - - // Run the test - try { - $parser->parse( $input, $title, $opts ); - $this->assertTrue( true, "Test $id, fuzz seed {$this->fuzzSeed}" ); - } catch ( Exception $exception ) { - $input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input ); - - $this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\nInput: $input_dump\n\nError: {$exception->getMessage()}\n\nBacktrace: {$exception->getTraceAsString()}" ); - } - - $this->teardownGlobals(); - $parser->__destruct(); - - if ( $id % 100 == 0 ) { - $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 ); - //echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n"; - if ( $usage > 90 ) { - $ret = "Out of memory:\n"; - $memStats = $this->getMemoryBreakdown(); - - foreach ( $memStats as $name => $usage ) { - $ret .= "$name: $usage\n"; - } - - throw new MWException( $ret ); - } - } - - $id++; - - } - } - - //Various getter functions - - /** - * Get an input dictionary from a set of parser test files - */ - function getFuzzInput( $filenames ) { - $dict = ''; - - foreach ( $filenames as $filename ) { - $contents = file_get_contents( $filename ); - preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); - - foreach ( $matches[1] as $match ) { - $dict .= $match . "\n"; - } - } - - return $dict; - } - - /** - * Get a memory usage breakdown - */ - function getMemoryBreakdown() { - $memStats = array(); - - foreach ( $GLOBALS as $name => $value ) { - $memStats['$' . $name] = strlen( serialize( $value ) ); - } - - $classes = get_declared_classes(); - - foreach ( $classes as $class ) { - $rc = new ReflectionClass( $class ); - $props = $rc->getStaticProperties(); - $memStats[$class] = strlen( serialize( $props ) ); - $methods = $rc->getMethods(); - - foreach ( $methods as $method ) { - $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); - } - } - - $functions = get_defined_functions(); - - foreach ( $functions['user'] as $function ) { - $rf = new ReflectionFunction( $function ); - $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); - } - - asort( $memStats ); - - return $memStats; - } - - /** - * Get a Parser object - */ - function getParser( $preprocessor = null ) { - global $wgParserConf; - - $class = $wgParserConf['class']; - $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); - - wfRunHooks( 'ParserTestParser', array( &$parser ) ); - - return $parser; - } - - //Various action functions - - public function addArticle( $name, $text, $line ) { - self::$articles[$name] = array( $text, $line ); - } - - public function publishTestArticles() { - if ( empty( self::$articles ) ) { - return; - } - - foreach ( self::$articles as $name => $info ) { - list( $text, $line ) = $info; - ParserTest::addArticle( $name, $text, $line, 'ignoreduplicate' ); - } - } - - /** - * Steal a callback function from the primary parser, save it for - * application to our scary parser. If the hook is not installed, - * abort processing of this file. - * - * @param $name String - * @return Bool true if tag hook is present - */ - public function requireHook( $name ) { - global $wgParser; - $wgParser->firstCallInit( ); // make sure hooks are loaded. - return isset( $wgParser->mTagHooks[$name] ); - } - - public function requireFunctionHook( $name ) { - global $wgParser; - $wgParser->firstCallInit( ); // make sure hooks are loaded. - return isset( $wgParser->mFunctionHooks[$name] ); - } - //Various "cleanup" functions - - /** - * Run the "tidy" command on text if the $wgUseTidy - * global is true - * - * @param $text String: the text to tidy - * @return String - */ - protected function tidy( $text ) { - global $wgUseTidy; - - if ( $wgUseTidy ) { - $text = MWTidy::tidy( $text ); - } - - return $text; - } - - /** - * Remove last character if it is a newline - */ - public function removeEndingNewline( $s ) { - if ( substr( $s, -1 ) === "\n" ) { - return substr( $s, 0, -1 ); - } - else { - return $s; - } - } - - //Test options parser functions - - protected function parseOptions( $instring ) { - $opts = array(); - // foo - // foo=bar - // foo="bar baz" - // foo=[[bar baz]] - // foo=bar,"baz quux" - $regex = '/\b - ([\w-]+) # Key - \b - (?:\s* - = # First sub-value - \s* - ( - " - [^"]* # Quoted val - " - | - \[\[ - [^]]* # Link target - \]\] - | - [\w-]+ # Plain word - ) - (?:\s* - , # Sub-vals 1..N - \s* - ( - "[^"]*" # Quoted val - | - \[\[[^]]*\]\] # Link target - | - [\w-]+ # Plain word - ) - )* - )? - /x'; - - if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) { - foreach ( $matches as $bits ) { - array_shift( $bits ); - $key = strtolower( array_shift( $bits ) ); - if ( count( $bits ) == 0 ) { - $opts[$key] = true; - } elseif ( count( $bits ) == 1 ) { - $opts[$key] = $this->cleanupOption( array_shift( $bits ) ); - } else { - // Array! - $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits ); - } - } - } - return $opts; - } - - protected function cleanupOption( $opt ) { - if ( substr( $opt, 0, 1 ) == '"' ) { - return substr( $opt, 1, -1 ); - } - - if ( substr( $opt, 0, 2 ) == '[[' ) { - return substr( $opt, 2, -2 ); - } - return $opt; - } - - /** - * Use a regex to find out the value of an option - * @param $key String: name of option val to retrieve - * @param $opts Options array to look in - * @param $default Mixed: default value returned if not found - */ - protected static function getOptionValue( $key, $opts, $default ) { - $key = strtolower( $key ); - - if ( isset( $opts[$key] ) ) { - return $opts[$key]; - } else { - return $default; - } - } -} diff --git a/tests/phpunit/includes/parser/ParserMethodsTest.php b/tests/phpunit/includes/parser/ParserMethodsTest.php deleted file mode 100644 index dea406c3..00000000 --- a/tests/phpunit/includes/parser/ParserMethodsTest.php +++ /dev/null @@ -1,33 +0,0 @@ -~~~', - 'hello \'\'this\'\' is ~~~', - ), - ); - } - - /** - * @dataProvider dataPreSaveTransform - */ - public function testPreSaveTransform( $text, $expected ) { - global $wgParser; - - $title = Title::newFromText( str_replace( '::', '__', __METHOD__ ) ); - $user = new User(); - $user->setName( "127.0.0.1" ); - $popts = ParserOptions::newFromUser( $user ); - $text = $wgParser->preSaveTransform( $text, $title, $user, $popts ); - - $this->assertEquals( $expected, $text ); - } - - // TODO: Add tests for cleanSig() / cleanSigInSig(), getSection(), replaceSection(), getPreloadText() -} - diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php deleted file mode 100644 index 0e8ef530..00000000 --- a/tests/phpunit/includes/parser/ParserPreloadTest.php +++ /dev/null @@ -1,67 +0,0 @@ -testParserOptions = new ParserOptions(); - - $this->testParser = new Parser(); - $this->testParser->Options( $this->testParserOptions ); - $this->testParser->clearState(); - - $this->title = Title::newFromText( 'Preload Test' ); - } - - function tearDown() { - unset( $this->testParser ); - unset( $this->title ); - } - - /** - * @covers Parser::getPreloadText - */ - function testPreloadSimpleText() { - $this->assertPreloaded( 'simple', 'simple' ); - } - - /** - * @covers Parser::getPreloadText - */ - function testPreloadedPreIsUnstripped() { - $this->assertPreloaded( - '
    monospaced
    ', - '
    monospaced
    ', - '
     in preloaded text must be unstripped (bug 27467)'
    -		);
    -	}
    -
    -	/**
    -	 * @covers Parser::getPreloadText
    -	 */
    -	function testPreloadedNowikiIsUnstripped() {
    -		$this->assertPreloaded(
    -			'[[Dummy title]]',
    -			'[[Dummy title]]',
    -			' in preloaded text must be unstripped (bug 27467)'
    -		);
    -	}
    -
    -	function assertPreloaded( $expected, $text, $msg='') {
    -		$this->assertEquals(
    -			$expected,
    -			$this->testParser->getPreloadText(
    -				$text,
    -				$this->title,
    -				$this->testParserOptions
    -			),
    -			$msg
    -		);
    -	}
    -
    -}
    diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php
    deleted file mode 100644
    index fee56748..00000000
    --- a/tests/phpunit/includes/parser/PreprocessorTest.php
    +++ /dev/null
    @@ -1,233 +0,0 @@
    -mOptions = new ParserOptions();
    -		$name = isset( $wgParserConf['preprocessorClass'] ) ? $wgParserConf['preprocessorClass'] : 'Preprocessor_DOM';
    -
    -		$this->mPreprocessor = new $name( $this );
    -	}
    -
    -	function getStripList() {
    -		return array( 'gallery', 'display map' /* Used by Maps, see r80025 CR */, '/foo' );
    -	}
    -
    -	function provideCases() {
    -		return array(
    -			array( "Foo", "Foo" ),
    -			array( "", "<!-- Foo -->" ),
    -			array( "", "<!-- Foo --><!-- Bar -->" ),
    -			array( "  ", "<!-- Foo -->  <!-- Bar -->" ),
    -			array( " \n ", "<!-- Foo --> \n <!-- Bar -->" ),
    -			array( " \n \n", "<!-- Foo --> \n <!-- Bar -->\n" ),
    -			array( "  \n", "<!-- Foo -->  <!-- Bar -->\n" ),
    -			array( "Bar", "<!-->Bar" ),
    -			array( "\n== Baz ==\n", "== Foo ==\n  <!-- Bar -->\n== Baz ==\n" ),
    -			array( "", "gallery" ),
    -			array( "Foo  Bar", "Foo gallery Bar" ),
    -			array( "", "gallery</gallery>" ),
    -			array( " ", "<foo> gallery</gallery>" ),
    -			array( " ", "<foo> gallery<gallery></gallery>" ),
    -			array( " Foo bar ", "<noinclude> Foo bar </noinclude>" ),
    -			array( "\n{{Foo}}\n", "<noinclude>\n\n</noinclude>" ),
    -			array( "\n{{Foo}}\n\n", "<noinclude>\n\n</noinclude>\n" ),
    -			array( "foo bar", "galleryfoo bar" ),
    -			array( "<{{foo}}>", "<>" ),
    -			array( "<{{{foo}}}>", "<foo>" ),
    -			array( "", "gallery</gallery</gallery>" ),
    -			array( "=== Foo === ", "=== Foo === " ),
    -			array( "=== Foo === ", "==<!-- -->= Foo === " ),
    -			array( "=== Foo === ", "=== Foo ==<!-- -->= " ),
    -			array( "=== Foo ===\n", "=== Foo ===<!-- -->\n" ),
    -			array( "=== Foo === \n", "=== Foo ===<!-- --> <!-- -->\n" ),
    -			array( "== Foo ==\n== Bar == \n", "== Foo ==\n== Bar == \n" ),
    -			array( "===========", "===========" ),
    -			array( "Foo\n=\n==\n=\n", "Foo\n=\n==\n=\n" ),
    -			array( "{{Foo}}", "" ),
    -			array( "\n{{Foo}}", "\n" ),
    -			array( "{{Foo|bar}}", "" ),  
    -			array( "{{Foo|bar}}a", "a" ),  
    -			array( "{{Foo|bar|baz}}", "" ),  
    -			array( "{{Foo|1=bar}}", "" ),
    -			array( "{{Foo|=bar}}", "" ),
    -			array( "{{Foo|bar=baz}}", "" ), 
    -			array( "{{Foo|{{bar}}=baz}}", "" ),
    -			array( "{{Foo|1=bar|baz}}", "" ), 
    -			array( "{{Foo|1=bar|2=baz}}", "" ),
    -			array( "{{Foo|bar|foo=baz}}", "" ), 
    -			array( "{{{1}}}", "1" ),
    -			array( "{{{1|}}}", "1" ),
    -			array( "{{{Foo}}}", "Foo" ),
    -			array( "{{{Foo|}}}", "Foo" ),
    -			array( "{{{Foo|bar|baz}}}", "Foobarbaz" ),
    -			array( "{{Foo}}", "{<!-- -->{Foo}}" ),
    -			array( "{{{{Foobar}}}}", "{Foobar}" ),
    -			array( "{{{ {{Foo}} }}}", " <template><title>Foo " ),
    -			array( "{{ {{{Foo}}} }}", "" ),
    -			array( "{{{{{Foo}}}}}", "" ),
    -			array( "{{{{{Foo}} }}}", "<template><title>Foo " ),
    -			array( "{{{{{{Foo}}}}}}", "<tplarg><title>Foo" ),
    -			array( "{{{{{{Foo}}}}}", "{" ),
    -			array( "[[[Foo]]", "[[[Foo]]" ),
    -			array( "{{Foo|[[[[bar]]|baz]]}}", "" ), // This test is important, since it means the difference between having the [[ rule stacked or not
    -			array( "{{Foo|[[[[bar]|baz]]}}", "{{Foo|[[[[bar]|baz]]}}" ),
    -			array( "{{Foo|Foo [[[[bar]|baz]]}}", "{{Foo|Foo [[[[bar]|baz]]}}" ),
    -			array( "Foo BarBaz", "Foo display mapBar</display map             >Baz" ),
    -			array( "Foo BarBaz", "Foo display map fooBar</display map             >Baz" ),
    -			array( "Foo ", "Foo gallery bar="baz" " ),
    -			array( "Foo ", "Foo gallery bar="1" baz=2 " ),
    -			array( "Foo", "/fooFoo<//foo>" ), # Worth blacklisting IMHO
    -			array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", ""),
    -			array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", ""),
    -			array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", ""),
    -			array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", ""),
    -			array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", ""),
    -			array( "{{ {{Foo}}", "{{ "),
    -			array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "{{Foobar    "),
    -			array( "[[Foo]] |", "[[Foo]] |"),
    -			array( "{{Foo|Bar|", "{{Foo|Bar|"),
    -			array( "[[Foo]", "[[Foo]"),
    -			array( "[[Foo|Bar]", "[[Foo|Bar]"),
    -			array( "{{Foo| [[Bar] }}", "{{Foo| [[Bar] }}"),
    -			array( "{{Foo| [[Bar|Baz] }}", "{{Foo| [[Bar|Baz] }}"),
    -			array( "{{Foo|bar=[[baz]}}", "{{Foo|bar=[[baz]}}"),
    -			array( "{{foo|", "{{foo|"),
    -			array( "{{foo|}", "{{foo|}"),
    -			array( "{{foo|} }}", ""),
    -			array( "{{foo|bar=|}", "{{foo|bar=|}"),
    -			array( "{{Foo|} Bar=", "{{Foo|} Bar="),
    -			array( "{{Foo|} Bar=}}", ""),
    -			/* array( file_get_contents( __DIR__ . '/QuoteQuran.txt' ), file_get_contents( __DIR__ . '/QuoteQuranExpanded.txt' ) ), */
    -		);
    -	}
    -
    -	/**
    -	 * Get XML preprocessor tree from the preprocessor (which may not be the
    -	 * native XML-based one).
    -	 *
    -	 * @param string $wikiText
    -	 * @return string
    -	 */
    -	function preprocessToXml( $wikiText ) {
    -		if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) {
    -			return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) );
    -		}
    -		
    -		$dom = $this->mPreprocessor->preprocessToObj( $wikiText );
    -		if ( is_callable( array( $dom, 'saveXML' ) ) ) {
    -			return $dom->saveXML();
    -		} else {
    -			return $this->normalizeXml( $dom->__toString() );
    -		}
    -	}
    -
    -	/**
    -	 * Normalize XML string to the form that a DOMDocument saves out.
    -	 *
    -	 * @param string $xml
    -	 * @return string
    -	 */
    -	function normalizeXml( $xml ) {
    -		return preg_replace( '!<([a-z]+)/>!', '<$1>', str_replace( ' />', '/>', $xml ) );
    -		
    -		$dom = new DOMDocument();
    -		// 1 << 19 == XML_PARSE_HUGE, needed so newer versions of libxml2 don't barf when the XML is >256 levels deep
    -		$dom->loadXML( $xml, 1 << 19 );
    -		return $dom->saveXML();
    -	}
    -
    -	/**
    -	 * @dataProvider provideCases
    -	 */
    -	function testPreprocessorOutput( $wikiText, $expectedXml ) {
    -		$this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
    -	}
    -
    -	/**
    -	 * These are more complex test cases taken out of wiki articles.
    -	 */
    -	function provideFiles() {
    -		return array(
    -			array( "QuoteQuran" ), # http://en.wikipedia.org/w/index.php?title=Template:QuoteQuran/sandbox&oldid=237348988 GFDL + CC-BY-SA by Striver
    -			array( "Factorial" ), # http://en.wikipedia.org/w/index.php?title=Template:Factorial&oldid=98548758 GFDL + CC-BY-SA by Polonium
    -			array( "All_system_messages" ), # http://tl.wiktionary.org/w/index.php?title=Suleras:All_system_messages&oldid=2765 GPL text generated by MediaWiki
    -			array( "Fundraising" ), # http://tl.wiktionary.org/w/index.php?title=MediaWiki:Sitenotice&oldid=5716 GFDL + CC-BY-SA, copied there by Sky Harbor.
    -		);
    -	}
    -
    -	/**
    -	 * @dataProvider provideFiles
    -	 */
    -	function testPreprocessorOutputFiles( $filename ) {
    -		$folder = __DIR__ . "/../../../parser/preprocess";
    -		$wikiText = file_get_contents( "$folder/$filename.txt" );
    -		$output = $this->preprocessToXml( $wikiText );
    -
    -		$expectedFilename = "$folder/$filename.expected";
    -		if ( file_exists( $expectedFilename ) ) {
    -			$expectedXml = $this->normalizeXml( file_get_contents( $expectedFilename ) );
    -			$this->assertEquals( $expectedXml, $output );
    -		} else {
    -			$tempFilename = tempnam( $folder, "$filename." );
    -			file_put_contents( $tempFilename, $output );
    -			$this->markTestIncomplete( "File $expectedFilename missing. Output stored as $tempFilename" );
    -		}
    -	}
    -
    -	/**
    -	 * Tests from Bug 28642 · https://bugzilla.wikimedia.org/28642
    -	 */
    -	function provideHeadings() {
    -		return array(	/* These should become headings: */
    -			array( "== h ==", "== h ==<!--c1-->" ),
    -			array( "== h == 	", "== h == 	<!--c1-->" ),
    -			array( "== h == 	", "== h ==<!--c1--> 	" ),
    -			array( "== h == 	 	", "== h == 	<!--c1--> 	" ),
    -			array( "== h ==", "== h ==<!--c1--><!--c2-->" ),
    -			array( "== h == 	", "== h == 	<!--c1--><!--c2-->" ),
    -			array( "== h == 	", "== h ==<!--c1--><!--c2--> 	" ),
    -			array( "== h == 	 	", "== h == 	<!--c1--><!--c2--> 	" ),
    -			array( "== h == 	  ", "== h == 	<!--c1-->  <!--c2-->" ),
    -			array( "== h ==   	", "== h ==<!--c1-->  <!--c2--> 	" ),
    -			array( "== h == 	   	", "== h == 	<!--c1-->  <!--c2--> 	" ),
    -			array( "== h ==", "== h ==<!--c1--><!--c2--><!--c3-->" ),
    -			array( "== h ==  ", "== h ==<!--c1-->  <!--c2--><!--c3-->" ),
    -			array( "== h ==  ", "== h ==<!--c1--><!--c2-->  <!--c3-->" ),
    -			array( "== h ==    ", "== h ==<!--c1-->  <!--c2-->  <!--c3-->" ),
    -			array( "== h ==  ", "== h ==  <!--c1--><!--c2--><!--c3-->" ),
    -			array( "== h ==    ", "== h ==  <!--c1-->  <!--c2--><!--c3-->" ),
    -			array( "== h ==    ", "== h ==  <!--c1--><!--c2-->  <!--c3-->" ),
    -			array( "== h ==      ", "== h ==  <!--c1-->  <!--c2-->  <!--c3-->" ),
    -			array( "== h ==  ", "== h ==<!--c1--><!--c2--><!--c3-->  " ),
    -			array( "== h ==    ", "== h ==<!--c1-->  <!--c2--><!--c3-->  " ),
    -			array( "== h ==    ", "== h ==<!--c1--><!--c2-->  <!--c3-->  " ),
    -			array( "== h ==      ", "== h ==<!--c1-->  <!--c2-->  <!--c3-->  " ),
    -			array( "== h ==    ", "== h ==  <!--c1--><!--c2--><!--c3-->  " ),
    -			array( "== h ==      ", "== h ==  <!--c1-->  <!--c2--><!--c3-->  " ),
    -			array( "== h ==      ", "== h ==  <!--c1--><!--c2-->  <!--c3-->  " ),
    -			array( "== h ==        ", "== h ==  <!--c1-->  <!--c2-->  <!--c3-->  " ),
    -
    -			/* These are not working: */
    -			array( "== h == 	", "== h ==<!--c1--> 	<!--c2-->" ),
    -			array( "== h == 	 	", "== h == 	<!--c1--> 	<!--c2-->" ),
    -			array( "== h == 	 	", "== h ==<!--c1--> 	<!--c2--> 	" ),
    -			array( "== h == x   ", "== h == x <!--c1--><!--c2--><!--c3-->  " ),
    -			array( "== h == x   ", "== h ==<!--c1--> x <!--c2--><!--c3-->  " ),
    -			array( "== h == x ", "== h ==<!--c1--><!--c2--><!--c3--> x " ),
    -		);
    -	}
    -
    -	/**
    -	 * @dataProvider provideHeadings
    -	 */
    -	function testHeadings( $wikiText, $expectedXml ) {
    -		$this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
    -	}
    -}
    -
    diff --git a/tests/phpunit/includes/parser/TagHooksTest.php b/tests/phpunit/includes/parser/TagHooksTest.php
    deleted file mode 100644
    index 713ce846..00000000
    --- a/tests/phpunit/includes/parser/TagHooksTest.php
    +++ /dev/null
    @@ -1,77 +0,0 @@
    -bar" ), array( "foo\nbar" ),  array( "foo\rbar" ) );
    -	}
    -		
    -	/**
    -	 * @dataProvider provideValidNames
    -	 */
    -	function testTagHooks( $tag ) {
    -		global $wgParserConf;
    -		$parser = new Parser( $wgParserConf );
    -		
    -		$parser->setHook( $tag, array( $this, 'tagCallback' ) );
    -		$parserOutput = $parser->parse( "Foo<$tag>BarBaz", Title::newFromText( 'Test' ), new ParserOptions );
    -		$this->assertEquals( "

    FooOneBaz\n

    ", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - function testBadTagHooks( $tag ) { - global $wgParserConf; - $parser = new Parser( $wgParserConf ); - - $parser->setHook( $tag, array( $this, 'tagCallback' ) ); - $parser->parse( "Foo<$tag>BarBaz", Title::newFromText( 'Test' ), new ParserOptions ); - $this->fail('Exception not thrown.'); - } - - /** - * @dataProvider provideValidNames - */ - function testFunctionTagHooks( $tag ) { - global $wgParserConf; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), 0 ); - $parserOutput = $parser->parse( "Foo<$tag>BarBaz", Title::newFromText( 'Test' ), new ParserOptions ); - $this->assertEquals( "

    FooOneBaz\n

    ", $parserOutput->getText() ); - - $parser->mPreprocessor = null; # Break the Parser <-> Preprocessor cycle - } - - /** - * @dataProvider provideBadNames - * @expectedException MWException - */ - function testBadFunctionTagHooks( $tag ) { - global $wgParserConf; - $parser = new Parser( $wgParserConf ); - - $parser->setFunctionTagHook( $tag, array( $this, 'functionTagCallback' ), SFH_OBJECT_ARGS ); - $parser->parse( "Foo<$tag>BarBaz", Title::newFromText( 'Test' ), new ParserOptions ); - $this->fail('Exception not thrown.'); - } - - function tagCallback( $text, $params, $parser ) { - return str_rot13( $text ); - } - - function functionTagCallback( &$parser, $frame, $code, $attribs ) { - return str_rot13( $code ); - } -} diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php deleted file mode 100644 index 957907c7..00000000 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ /dev/null @@ -1,163 +0,0 @@ -search ); - } - - /** - * Checks for database type & version. - * Will skip current test if DB does not support search. - */ - function setUp() { - parent::setUp(); - // Search tests require MySQL or SQLite with FTS - # Get database type and version - $dbType = $this->db->getType(); - $dbSupported = - ($dbType === 'mysql') - || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' ); - - if( !$dbSupported ) { - $this->markTestSkipped( "MySQL or SQLite with FTS3 only" ); - } - - $searchType = $this->db->getSearchEngine(); - $this->search = new $searchType( $this->db ); - } - - function pageExists( $title ) { - return false; - } - - function addDBData() { - if ( $this->pageExists( 'Not_Main_Page' ) ) { - return; - } - $this->insertPage( "Not_Main_Page", "This is not a main page", 0 ); - $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 ); - $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 ); - $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 ); - $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 ); - $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 ); - $this->insertPage( 'Help:Help', 'Help me!', 4 ); - $this->insertPage( 'Thppt', 'Blah blah', 0 ); - $this->insertPage( 'Alan_Smithee', 'yum', 0 ); - $this->insertPage( 'Pages', 'are\'food', 0 ); - $this->insertPage( 'HalfOneUp', 'AZ', 0 ); - $this->insertPage( 'FullOneUp', 'AZ', 0 ); - $this->insertPage( 'HalfTwoLow', 'az', 0 ); - $this->insertPage( 'FullTwoLow', 'az', 0 ); - $this->insertPage( 'HalfNumbers', '1234567890', 0 ); - $this->insertPage( 'FullNumbers', '1234567890', 0 ); - $this->insertPage( 'DomainName', 'example.com', 0 ); - } - - function fetchIds( $results ) { - $this->assertTrue( is_object( $results ) ); - - $matches = array(); - $row = $results->next(); - while ( $row ) { - $matches[] = $row->getTitle()->getPrefixedText(); - $row = $results->next(); - } - $results->free(); - # Search is not guaranteed to return results in a certain order; - # sort them numerically so we will compare simply that we received - # the expected matches. - sort( $matches ); - return $matches; - } - - /** - * Insert a new page - * - * @param $pageName String: page name - * @param $text String: page's content - * @param $n Integer: unused - */ - function insertPage( $pageName, $text, $ns ) { - $title = Title::newFromText( $pageName ); - - $user = User::newFromName( 'WikiSysop' ); - $comment = 'Search Test'; - - // avoid memory leak...? - LinkCache::singleton()->clear(); - - $page = WikiPage::factory( $title ); - $page->doEdit( $text, $comment, 0, false, $user ); - - $this->pageList[] = array( $title, $page->getId() ); - - return true; - } - - function testFullWidth() { - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Half-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Half-width Lower" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Full-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Full-width Lower" ); - } - - function testTextSearch() { - $this->assertEquals( - array( 'Smithee' ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Plain search failed" ); - } - - function testTextPowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Smithee', - 'Talk:Not Main Page', - ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Power search failed" ); - } - - function testTitleSearch() { - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title search failed" ); - } - - function testTextTitlePowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - 'Talk:Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title power search failed" ); - } - -} diff --git a/tests/phpunit/includes/search/SearchUpdateTest.php b/tests/phpunit/includes/search/SearchUpdateTest.php deleted file mode 100644 index 6e49a9a1..00000000 --- a/tests/phpunit/includes/search/SearchUpdateTest.php +++ /dev/null @@ -1,90 +0,0 @@ -doUpdate(); - return array( MockSearch::$title, MockSearch::$text ); - } - - function updateText( $text ) { - list( , $resultText ) = $this->update( $text ); - $resultText = trim( $resultText ); // abstract from some implementation details - return $resultText; - } - - function setUp() { - global $wgSearchType; - - self::$searchType = $wgSearchType; - $wgSearchType = 'MockSearch'; - } - - function tearDown() { - global $wgSearchType; - - $wgSearchType = self::$searchType; - } - - function testUpdateText() { - $this->assertEquals( - 'test', - $this->updateText( '
    TeSt
    ' ), - 'HTML stripped, text lowercased' - ); - - $this->assertEquals( - 'foo bar boz quux', - $this->updateText( << -
    foo
    bar - bozquux - -EOT - ), 'Stripping HTML tables' ); - - $this->assertEquals( - 'a b', - $this->updateText( 'a > b' ), - 'Handle unclosed tags' - ); - - $text = str_pad( "foo assertNotEquals( - '', - $this->updateText( $text ), - 'Bug 18609' - ); - } - - function testBug32712() { - $text = "text „http://example.com“ text"; - $result = $this->updateText( $text ); - $processed = preg_replace( '/Q/u', 'Q', $result ); - $this->assertTrue( - $processed != '', - 'Link surrounded by unicode quotes should not fail UTF-8 validation' - ); - } -} diff --git a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php b/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php deleted file mode 100644 index a33c7b68..00000000 --- a/tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php +++ /dev/null @@ -1,79 +0,0 @@ -manualTest ) ) { - $this->queryPages[$class] = new $class; - } - } - } - - /** - * Test SQL for each of our QueryPages objects - * @group Database - */ - function testQuerypageSqlQuery() { - global $wgDBtype; - - foreach( $this->queryPages as $page ) { - - // With MySQL, skips special pages reopening a temporary table - // See http://bugs.mysql.com/bug.php?id=10327 - if( - $wgDBtype === 'mysql' - && in_array( $page->getName(), $this->reopensTempTable ) - ) { - $this->markTestSkipped( "SQL query for page {$page->getName()} can not be tested on MySQL backend (it reopens a temporary table)" ); - continue; - } - - $msg = "SQL query for page {$page->getName()} should give a result wrapper object" ; - - $result = $page->reallyDoQuery( 50 ); - if( $result instanceof ResultWrapper ) { - $this->assertTrue( true, $msg ); - } else { - $this->assertFalse( false, $msg ); - } - } - } -} diff --git a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php b/tests/phpunit/includes/specials/SpecialRecentchangesTest.php deleted file mode 100644 index 2e4f4b09..00000000 --- a/tests/phpunit/includes/specials/SpecialRecentchangesTest.php +++ /dev/null @@ -1,132 +0,0 @@ -setRequest( new FauxRequest( $requestOptions ) ); - - # setup the rc object - $this->rc = new SpecialRecentChanges(); - $this->rc->setContext( $context ); - $formOptions = $this->rc->setup( null ); - - # Filter out rc_timestamp conditions which depends on the test runtime - # This condition is not needed as of march 2, 2011 -- hashar - # @todo FIXME: Find a way to generate the correct rc_timestamp - $queryConditions = array_filter( - $this->rc->buildMainQueryConds( $formOptions ), - 'SpecialRecentchangesTest::filterOutRcTimestampCondition' - ); - - $this->assertEquals( - $expected, - $queryConditions, - $message - ); - } - - /** return false if condition begin with 'rc_timestamp ' */ - private static function filterOutRcTimestampCondition( $var ) { - return (false === strpos( $var, 'rc_timestamp ' )); - - } - - public function testRcNsFilter() { - $this->assertConditions( - array( # expected - 'rc_bot' => 0, - #0 => "rc_timestamp >= '20110223000000'", - 1 => "rc_namespace = '0'", - ), - array( - 'namespace' => NS_MAIN, - ), - "rc conditions with no options (aka default setting)" - ); - } - - public function testRcNsFilterInversion() { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "rc_namespace != '%s'", NS_MAIN ), - ), - array( - 'namespace' => NS_MAIN, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociation( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace = '%s' OR rc_namespace = '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * @bug 2429 - * @dataProvider provideNamespacesAssociations - */ - public function testRcNsFilterAssociationWithInversion( $ns1, $ns2 ) { - $this->assertConditions( - array( # expected - #0 => "rc_timestamp >= '20110223000000'", - 'rc_bot' => 0, - 1 => sprintf( "(rc_namespace != '%s' AND rc_namespace != '%s')", $ns1, $ns2 ), - ), - array( - 'namespace' => $ns1, - 'associated' => 1, - 'invert' => 1, - ), - "rc conditions with namespace inverted" - ); - } - - /** - * Provides associated namespaces to test recent changes - * namespaces association filtering. - */ - public function provideNamespacesAssociations() { - return array( # (NS => Associated_NS) - array( NS_MAIN, NS_TALK), - array( NS_TALK, NS_MAIN), - ); - } - -} - - diff --git a/tests/phpunit/includes/specials/SpecialSearchTest.php b/tests/phpunit/includes/specials/SpecialSearchTest.php deleted file mode 100644 index 20e42a68..00000000 --- a/tests/phpunit/includes/specials/SpecialSearchTest.php +++ /dev/null @@ -1,116 +0,0 @@ - true, 'ns6' => true). NULL to use default options. - * @param $userOptions Array User options to test with. For example array('searchNs5' => 1 );. NULL to use default options. - * @param $expectedProfile An expected search profile name - * @param $expectedNs Array Expected namespaces - */ - function testProfileAndNamespaceLoading( - $requested, $userOptions, $expectedProfile, $expectedNS, - $message = 'Profile name and namespaces mismatches!' - ) { - $context = new RequestContext; - $context->setUser( - $this->newUserWithSearchNS( $userOptions ) - ); - /* - $context->setRequest( new FauxRequest( array( - 'ns5'=>true, - 'ns6'=>true, - ) )); - */ - $context->setRequest( new FauxRequest( $requested )); - $search = new SpecialSearch(); - $search->setContext( $context ); - $search->load(); - - /** - * Verify profile name and namespace in the same assertion to make - * sure we will be able to fully compare the above code. PHPUnit stop - * after an assertion fail. - */ - $this->assertEquals( - array( /** Expected: */ - 'ProfileName' => $expectedProfile, - 'Namespaces' => $expectedNS, - ) - , array( /** Actual: */ - 'ProfileName' => $search->getProfile(), - 'Namespaces' => $search->getNamespaces(), - ) - , $message - ); - - } - - function provideSearchOptionsTests() { - $defaultNS = SearchEngine::defaultNamespaces(); - $EMPTY_REQUEST = array(); - $NO_USER_PREF = null; - - return array( - /** - * Parameters: - * , - * Followed by expected values: - * , - * Then an optional message. - */ - array( - $EMPTY_REQUEST, $NO_USER_PREF, - 'default', $defaultNS, - 'Bug 33270: No request nor user preferences should give default profile' - ), - array( - array( 'ns5' => 1 ), $NO_USER_PREF, - 'advanced', array( 5), - 'Web request with specific NS should override user preference' - ), - array( - $EMPTY_REQUEST, array( 'searchNs2' => 1, 'searchNs14' => 1 ), - 'advanced', array( 2, 14 ), - 'Bug 33583: search with no option should honor User search preferences' - ), - array( - $EMPTY_REQUEST, array_fill_keys( array_map( function( $ns ) { - return "searchNs$ns"; - }, $defaultNS ), 0 ) + array( 'searchNs2' => 1, 'searchNs14' => 1 ), - 'advanced', array( 2, 14 ), - 'Bug 33583: search with no option should honor User search preferences' - . 'and have all other namespace disabled' - ), - ); - } - - /** - * Helper to create a new User object with given options - * User remains anonymous though - */ - function newUserWithSearchNS( $opt = null ) { - $u = User::newFromId(0); - if( $opt === null ) { - return $u; - } - foreach($opt as $name => $value) { - $u->setOption( $name, $value ); - } - return $u; - } -} - diff --git a/tests/phpunit/includes/upload/UploadFromUrlTest.php b/tests/phpunit/includes/upload/UploadFromUrlTest.php deleted file mode 100644 index f66c387b..00000000 --- a/tests/phpunit/includes/upload/UploadFromUrlTest.php +++ /dev/null @@ -1,351 +0,0 @@ -exists() ) { - $this->deleteFile( 'UploadFromUrlTest.png' ); - } - } - - protected function doApiRequest( Array $params, Array $unused = null, $appendModule = false, User $user = null ) { - $sessionId = session_id(); - session_write_close(); - - $req = new FauxRequest( $params, true, $_SESSION ); - $module = new ApiMain( $req, true ); - $module->execute(); - - wfSetupSession( $sessionId ); - return array( $module->getResultData(), $req ); - } - - /** - * Ensure that the job queue is empty before continuing - */ - public function testClearQueue() { - $job = Job::pop(); - while ( $job ) { - $job = Job::pop(); - } - $this->assertFalse( $job ); - } - - /** - * @todo Document why we test login, since the $wgUser hack used doesn't - * require login - */ - public function testLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - 'lgname' => $this->user->userName, - 'lgpassword' => $this->user->passWord ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSetupUrlDownload( $data ) { - $token = $this->user->getEditToken(); - $exception = false; - - try { - $this->doApiRequest( array( - 'action' => 'upload', - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The filename parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->removeGroup( 'sysop' ); - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "Permission denied", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $this->user->addGroup( 'sysop' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - - $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' ); - - $job = Job::pop(); - $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' ); - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUpload( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token, true ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUploadWarning( $data ) { - $token = $this->user->getEditToken(); - - $this->user->addGroup( 'users' ); - - - $data = $this->doAsyncUpload( $token ); - - $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); - $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'sessionkey' => $data[0]['upload']['sessionkey'], - 'filename' => 'UploadFromUrlTest.png', - 'ignorewarnings' => 1, - 'token' => $token, - ) ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSyncDownload( $data ) { - $token = $this->user->getEditToken(); - - $job = Job::pop(); - $this->assertFalse( $job, 'Starting with an empty jobqueue' ); - - $this->user->addGroup( 'users' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'ignorewarnings' => true, - 'token' => $token, - ), $data ); - - $job = Job::pop(); - $this->assertFalse( $job ); - - $this->assertEquals( 'Success', $data[0]['upload']['result'] ); - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - public function testLeaveMessage() { - $token = $this->user->user->getEditToken(); - - $talk = $this->user->user->getTalkPage(); - if ( $talk->exists() ) { - $page = WikiPage::factory( $talk ); - $page->doDeleteArticle( '' ); - } - - $this->assertFalse( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk does not exist' ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - 'ignorewarnings' => 1, - ) ); - - $job = Job::pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - $job->run(); - - $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - $this->assertTrue( (bool)$talk->getArticleID( Title::GAID_FOR_UPDATE ), 'User talk exists' ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - $talkRev = Revision::newFromTitle( $talk ); - $talkSize = $talkRev->getSize(); - - $exception = false; - try { - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() ); - } - $this->assertTrue( $exception ); - - $job = Job::pop(); - $this->assertFalse( $job ); - - return; - - /* - // Broken until using leavemessage with ignorewarnings is supported - $job->run(); - - $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - - $talkRev = Revision::newFromTitle( $talk ); - $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' ); - */ - } - - /** - * Helper function to perform an async upload, execute the job and fetch - * the status - * - * @return array The result of action=upload&statuskey=key - */ - private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) { - $params = array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - ); - if ( $ignoreWarnings ) { - $params['ignorewarnings'] = 1; - } - if ( $leaveMessage ) { - $params['leavemessage'] = 1; - } - - $data = $this->doApiRequest( $params ); - $this->assertEquals( $data[0]['upload']['result'], 'Queued' ); - $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) ); - $statusKey = $data[0]['upload']['statuskey']; - - $job = Job::pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - - $status = $job->run(); - $this->assertTrue( $status ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'statuskey' => $statusKey, - 'token' => $token, - ) ); - - return $data; - } - - - /** - * - */ - protected function deleteFile( $name ) { - $t = Title::newFromText( $name, NS_FILE ); - $this->assertTrue($t->exists(), "File '$name' exists"); - - if ( $t->exists() ) { - $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) ); - $empty = ""; - FileDeleteForm::doDelete( $t, $file, $empty, "none", true ); - $page = WikiPage::factory( $t ); - $page->doDeleteArticle( "testing" ); - } - $t = Title::newFromText( $name, NS_FILE ); - - $this->assertFalse($t->exists(), "File '$name' was deleted"); - } - } diff --git a/tests/phpunit/includes/upload/UploadStashTest.php b/tests/phpunit/includes/upload/UploadStashTest.php deleted file mode 100644 index 66fafaaf..00000000 --- a/tests/phpunit/includes/upload/UploadStashTest.php +++ /dev/null @@ -1,77 +0,0 @@ -bug29408File = __DIR__ . '/bug29408'; - file_put_contents( $this->bug29408File, "\x00" ); - - self::$users = array( - 'sysop' => new TestUser( - 'Uploadstashtestsysop', - 'Upload Stash Test Sysop', - 'upload_stash_test_sysop@example.com', - array( 'sysop' ) - ), - 'uploader' => new TestUser( - 'Uploadstashtestuser', - 'Upload Stash Test User', - 'upload_stash_test_user@example.com', - array() - ) - ); - } - - public function testBug29408() { - global $wgUser; - $wgUser = self::$users['uploader']->user; - - $repo = RepoGroup::singleton()->getLocalRepo(); - $stash = new UploadStash( $repo ); - - // Throws exception caught by PHPUnit on failure - $file = $stash->stashFile( $this->bug29408File ); - // We'll never reach this point if we hit bug 29408 - $this->assertTrue( true, 'Unrecognized file without extension' ); - - $stash->removeFile( $file->getFileKey() ); - } - - public function testValidRequest() { - $request = new FauxRequest( array( 'wpFileKey' => 'foo') ); - $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpFileKey' ); - - $request = new FauxRequest( array( 'wpSessionKey' => 'foo') ); - $this->assertFalse( UploadFromStash::isValidRequest($request), 'Check failure on bad wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') ); - $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpFileKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test') ); - $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check good wpSessionKey' ); - - $request = new FauxRequest( array( 'wpFileKey' => 'testkey-test.test', 'wpSessionKey' => 'foo') ); - $this->assertTrue( UploadFromStash::isValidRequest($request), 'Check key precedence' ); - } - - public function tearDown() { - parent::tearDown(); - - if( file_exists( $this->bug29408File . "." ) ) { - unlink( $this->bug29408File . "." ); - } - - if( file_exists( $this->bug29408File ) ) { - unlink( $this->bug29408File ); - } - } -} diff --git a/tests/phpunit/includes/upload/UploadTest.php b/tests/phpunit/includes/upload/UploadTest.php deleted file mode 100644 index 6948f5b1..00000000 --- a/tests/phpunit/includes/upload/UploadTest.php +++ /dev/null @@ -1,141 +0,0 @@ -upload = new UploadTestHandler; - $this->hooks = $wgHooks; - $wgHooks['InterwikiLoadPrefix'][] = function( $prefix, &$data ) { - return false; - }; - } - - function tearDown() { - global $wgHooks; - $wgHooks = $this->hooks; - } - - - /** - * First checks the return code - * of UploadBase::getTitle() and then the actual returned title - * - * @dataProvider dataTestTitleValidation - */ - public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) { - /* Check the result code */ - $this->assertEquals( $code, - $this->upload->testTitleValidation( $srcFilename ), - "$msg code" ); - - /* If we expect a valid title, check the title itself. */ - if ( $code == UploadBase::OK ) { - $this->assertEquals( $dstFilename, - $this->upload->getTitle()->getText(), - "$msg text" ); - } - } - - /** - * Test various forms of valid and invalid titles that can be supplied. - */ - public function dataTestTitleValidation() { - return array( - /* Test a valid title */ - array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, - 'upload valid title' ), - /* A title with a slash */ - array( 'A/B.jpg', 'B.jpg', UploadBase::OK, - 'upload title with slash' ), - /* A title with illegal char */ - array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, - 'upload title with colon' ), - /* Stripping leading File: prefix */ - array( 'File:C.jpg', 'C.jpg', UploadBase::OK, - 'upload title with File prefix' ), - /* Test illegal suggested title (r94601) */ - array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, - 'illegal title for upload' ), - /* A title without extension */ - array( 'A', null, UploadBase::FILETYPE_MISSING, - 'upload title without extension' ), - /* A title with no basename */ - array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, - 'upload title without basename' ), - /* A title that is longer than 255 bytes */ - array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 255 bytes' ), - /* A title that is longer than 240 bytes */ - array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, - 'upload title longer than 240 bytes' ), - ); - } - - /** - * Test the upload verification functions - */ - public function testVerifyUpload() { - /* Setup with zero file size */ - $this->upload->initializePathInfo( '', '', 0 ); - $result = $this->upload->verifyUpload(); - $this->assertEquals( UploadBase::EMPTY_FILE, - $result['status'], - 'upload empty file' ); - } - - // Helper used to create an empty file of size $size. - private function createFileOfSize( $size ) { - $filename = tempnam( wfTempDir(), "mwuploadtest" ); - - $fh = fopen( $filename, 'w' ); - ftruncate( $fh, $size ); - fclose( $fh ); - - return $filename; - } - - /** - * test uploading a 100 bytes file with $wgMaxUploadSize = 100 - * - * This method should be abstracted so we can test different settings. - */ - - public function testMaxUploadSize() { - global $wgMaxUploadSize; - $savedGlobal = $wgMaxUploadSize; // save global - global $wgFileExtensions; - $wgFileExtensions[] = 'txt'; - - $wgMaxUploadSize = 100; - - $filename = $this->createFileOfSize( $wgMaxUploadSize ); - $this->upload->initializePathInfo( basename($filename) . '.txt', $filename, 100 ); - $result = $this->upload->verifyUpload(); - unlink( $filename ); - - $this->assertEquals( - array( 'status' => UploadBase::OK ), $result ); - - $wgMaxUploadSize = $savedGlobal; // restore global - } -} - -class UploadTestHandler extends UploadBase { - public function initializeFromRequest( &$request ) { } - public function testTitleValidation( $name ) { - $this->mTitle = false; - $this->mDesiredDestName = $name; - $this->mTitleError = UploadBase::OK; - $this->getTitle(); - return $this->mTitleError; - } - - -} diff --git a/tests/phpunit/install-phpunit.sh b/tests/phpunit/install-phpunit.sh deleted file mode 100644 index 2d2b53ab..00000000 --- a/tests/phpunit/install-phpunit.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -has_binary () { - if [ -z `which $1` ]; then - return 1 - fi - return 0 -} - -if [ `id -u` -ne 0 ]; then - echo '*** ERROR' Must be root to run - exit 1 -fi - -if ( has_binary phpunit ); then - echo PHPUnit already installed -else if ( has_binary pear ); then - echo Installing phpunit with pear - pear channel-discover pear.phpunit.de - pear channel-discover components.ez.no - pear channel-discover pear.symfony-project.com - pear install phpunit/PHPUnit -else if ( has_binary apt-get ); then - echo Installing phpunit with apt-get - apt-get install phpunit -else if ( has_binary yum ); then - echo Installing phpunit with yum - yum install phpunit -else if ( has_binary port ); then - echo Installing phpunit with macports - port install php5-unit -fi -fi -fi -fi -fi diff --git a/tests/phpunit/languages/LanguageAmTest.php b/tests/phpunit/languages/LanguageAmTest.php deleted file mode 100644 index 3a648ded..00000000 --- a/tests/phpunit/languages/LanguageAmTest.php +++ /dev/null @@ -1,33 +0,0 @@ -lang = Language::factory( 'Am' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageArTest.php b/tests/phpunit/languages/LanguageArTest.php deleted file mode 100644 index b23e0534..00000000 --- a/tests/phpunit/languages/LanguageArTest.php +++ /dev/null @@ -1,78 +0,0 @@ -lang = Language::factory( 'Ar' ); - } - function tearDown() { - unset( $this->lang ); - } - - function testFormatNum() { - $this->assertEquals( '١٬٢٣٤٬٥٦٧', $this->lang->formatNum( '1234567' ) ); - $this->assertEquals( '-١٢٫٨٩', $this->lang->formatNum( -12.89 ) ); - } - - /** - * Mostly to test the raw ascii feature. - * @dataProvider providerSprintfDate - */ - function testSprintfDate( $format, $date, $expected ) { - $this->assertEquals( $expected, $this->lang->sprintfDate( $format, $date ) ); - } - - function providerSprintfDate() { - return array( - array( - 'xg "vs" g', - '20120102030410', - 'يناير vs ٣' - ), - array( - 'xmY', - '20120102030410', - '١٤٣٣' - ), - array( - 'xnxmY', - '20120102030410', - '1433' - ), - array( - 'xN xmj xmn xN xmY', - '20120102030410', - ' 7 2 ١٤٣٣' - ), - ); - } - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providePlural() { - return array ( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 9 ), - array( 'few', 110 ), - array( 'many', 11 ), - array( 'many', 15 ), - array( 'many', 99 ), - array( 'many', 9999 ), - array( 'other', 100 ), - array( 'other', 102 ), - array( 'other', 1000 ), - array( 'other', 1.7 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBeTest.php b/tests/phpunit/languages/LanguageBeTest.php deleted file mode 100644 index 735ccc63..00000000 --- a/tests/phpunit/languages/LanguageBeTest.php +++ /dev/null @@ -1,40 +0,0 @@ -lang = Language::factory( 'Be' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageBe_taraskTest.php b/tests/phpunit/languages/LanguageBe_taraskTest.php deleted file mode 100644 index 765cdb8f..00000000 --- a/tests/phpunit/languages/LanguageBe_taraskTest.php +++ /dev/null @@ -1,65 +0,0 @@ -lang = Language::factory( 'Be-tarask' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** see bug 23156 & r64981 */ - function testSearchRightSingleQuotationMarkAsApostroph() { - $this->assertEquals( - "'", - $this->lang->normalizeForSearch( '’' ), - 'bug 23156: U+2019 conversion to U+0027' - ); - } - /** see bug 23156 & r64981 */ - function testCommafy() { - $this->assertEquals( '1,234,567', $this->lang->commafy( '1234567' ) ); - $this->assertEquals( '12,345', $this->lang->commafy( '12345' ) ); - } - /** see bug 23156 & r64981 */ - function testDoesNotCommafyFourDigitsNumber() { - $this->assertEquals( '1234', $this->lang->commafy( '1234' ) ); - } - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralFourForms() { - return array ( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providePluralTwoForms() { - return array ( - array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageBhTest.php b/tests/phpunit/languages/LanguageBhTest.php deleted file mode 100644 index e1e2a13e..00000000 --- a/tests/phpunit/languages/LanguageBhTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'Bh' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageBsTest.php b/tests/phpunit/languages/LanguageBsTest.php deleted file mode 100644 index b6631c03..00000000 --- a/tests/phpunit/languages/LanguageBsTest.php +++ /dev/null @@ -1,41 +0,0 @@ -lang = Language::factory( 'Bs' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 4 ), - array( 'many', 5 ), - array( 'many', 11 ), - array( 'many', 20 ), - array( 'one', 21 ), - array( 'few', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageCsTest.php b/tests/phpunit/languages/LanguageCsTest.php deleted file mode 100644 index dda29f9a..00000000 --- a/tests/phpunit/languages/LanguageCsTest.php +++ /dev/null @@ -1,40 +0,0 @@ -lang = Language::factory( 'cs' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageCuTest.php b/tests/phpunit/languages/LanguageCuTest.php deleted file mode 100644 index f8186d7b..00000000 --- a/tests/phpunit/languages/LanguageCuTest.php +++ /dev/null @@ -1,41 +0,0 @@ -lang = Language::factory( 'cu' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), - array( 'other', 5 ), - array( 'one', 11 ), - array( 'other', 20 ), - array( 'few', 22 ), - array( 'many', 223 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageCyTest.php b/tests/phpunit/languages/LanguageCyTest.php deleted file mode 100644 index e9f9e410..00000000 --- a/tests/phpunit/languages/LanguageCyTest.php +++ /dev/null @@ -1,42 +0,0 @@ -lang = Language::factory( 'cy' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'zero', 'one', 'two', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'many', 6 ), - array( 'other', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 22 ), - array( 'other', 223 ), - array( 'other', 200.00 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageDsbTest.php b/tests/phpunit/languages/LanguageDsbTest.php deleted file mode 100644 index ab7f9313..00000000 --- a/tests/phpunit/languages/LanguageDsbTest.php +++ /dev/null @@ -1,40 +0,0 @@ -lang = Language::factory( 'dsb' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'one', 101 ), - array( 'one', 90001 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 203 ), - array( 'few', 4 ), - array( 'other', 99 ), - array( 'other', 555 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageFrTest.php b/tests/phpunit/languages/LanguageFrTest.php deleted file mode 100644 index 8538744e..00000000 --- a/tests/phpunit/languages/LanguageFrTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'fr' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageGaTest.php b/tests/phpunit/languages/LanguageGaTest.php deleted file mode 100644 index fbd9f11d..00000000 --- a/tests/phpunit/languages/LanguageGaTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'ga' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageGdTest.php b/tests/phpunit/languages/LanguageGdTest.php deleted file mode 100644 index 24574bda..00000000 --- a/tests/phpunit/languages/LanguageGdTest.php +++ /dev/null @@ -1,38 +0,0 @@ -lang = Language::factory( 'gd' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - // The CLDR ticket for this plural forms is not same as mw plural forms. See http://unicode.org/cldr/trac/ticket/2883 - $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4', 'Form 5', 'Form 6' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providerPlural() { - return array ( - array( 'Form 6', 0 ), - array( 'Form 1', 1 ), - array( 'Form 2', 2 ), - array( 'Form 3', 11 ), - array( 'Form 4', 12 ), - array( 'Form 5', 3 ), - array( 'Form 5', 19 ), - array( 'Form 6', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageGvTest.php b/tests/phpunit/languages/LanguageGvTest.php deleted file mode 100644 index 3d298b9b..00000000 --- a/tests/phpunit/languages/LanguageGvTest.php +++ /dev/null @@ -1,39 +0,0 @@ -lang = Language::factory( 'gv' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - // This is not compatible with CLDR plural rules http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#gv - $forms = array( 'Form 1', 'Form 2', 'Form 3', 'Form 4' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providerPlural() { - return array ( - array( 'Form 4', 0 ), - array( 'Form 2', 1 ), - array( 'Form 3', 2 ), - array( 'Form 4', 3 ), - array( 'Form 1', 20 ), - array( 'Form 2', 21 ), - array( 'Form 3', 22 ), - array( 'Form 4', 23 ), - array( 'Form 4', 50 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageHeTest.php b/tests/phpunit/languages/LanguageHeTest.php deleted file mode 100644 index 7833da71..00000000 --- a/tests/phpunit/languages/LanguageHeTest.php +++ /dev/null @@ -1,48 +0,0 @@ -lang = Language::factory( 'he' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPluralDual */ - function testPluralDual( $result, $value ) { - $forms = array( 'one', 'two', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralDual() { - return array ( - array( 'other', 0 ), // Zero -> plural - array( 'one', 1 ), // Singular - array( 'two', 2 ), // Dual - array( 'other', 3 ), // Plural - ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), // Zero -> plural - array( 'one', 1 ), // Singular - array( 'other', 2 ), // Plural, no dual provided - array( 'other', 3 ), // Plural - ); - } -} diff --git a/tests/phpunit/languages/LanguageHiTest.php b/tests/phpunit/languages/LanguageHiTest.php deleted file mode 100644 index ead9e020..00000000 --- a/tests/phpunit/languages/LanguageHiTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'Hi' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageHrTest.php b/tests/phpunit/languages/LanguageHrTest.php deleted file mode 100644 index 4f1c66bf..00000000 --- a/tests/phpunit/languages/LanguageHrTest.php +++ /dev/null @@ -1,41 +0,0 @@ -lang = Language::factory( 'hr' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 4 ), - array( 'many', 5 ), - array( 'many', 11 ), - array( 'many', 20 ), - array( 'one', 21 ), - array( 'few', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageHsbTest.php b/tests/phpunit/languages/LanguageHsbTest.php deleted file mode 100644 index 803c7721..00000000 --- a/tests/phpunit/languages/LanguageHsbTest.php +++ /dev/null @@ -1,40 +0,0 @@ -lang = Language::factory( 'hsb' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'one', 101 ), - array( 'one', 90001 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 203 ), - array( 'few', 4 ), - array( 'other', 99 ), - array( 'other', 555 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageHuTest.php b/tests/phpunit/languages/LanguageHuTest.php deleted file mode 100644 index adbd37ec..00000000 --- a/tests/phpunit/languages/LanguageHuTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'Hu' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageHyTest.php b/tests/phpunit/languages/LanguageHyTest.php deleted file mode 100644 index 7990bdfc..00000000 --- a/tests/phpunit/languages/LanguageHyTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'hy' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageKshTest.php b/tests/phpunit/languages/LanguageKshTest.php deleted file mode 100644 index ab889464..00000000 --- a/tests/phpunit/languages/LanguageKshTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'ksh' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other', 'zero' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageLnTest.php b/tests/phpunit/languages/LanguageLnTest.php deleted file mode 100644 index 0fd9167e..00000000 --- a/tests/phpunit/languages/LanguageLnTest.php +++ /dev/null @@ -1,34 +0,0 @@ -lang = Language::factory( 'ln' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageLtTest.php b/tests/phpunit/languages/LanguageLtTest.php deleted file mode 100644 index 0d7c7d3e..00000000 --- a/tests/phpunit/languages/LanguageLtTest.php +++ /dev/null @@ -1,53 +0,0 @@ -lang = Language::factory( 'Lt' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider provideOneFewOtherCases */ - function testOneFewOtherPlural( $result, $value ) { - $forms = array( 'one', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - /** @dataProvider provideOneFewCases */ - function testOneFewPlural( $result, $value ) { - $forms = array( 'one', 'few' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function provideOneFewOtherCases() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 9 ), - array( 'other', 10 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'one', 21 ), - array( 'few', 32 ), - array( 'one', 41 ), - array( 'one', 40001 ), - ); - } - - function provideOneFewCases() { - return array ( - array( 'one', 1 ), - array( 'few', 15 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageLvTest.php b/tests/phpunit/languages/LanguageLvTest.php deleted file mode 100644 index 0636da5f..00000000 --- a/tests/phpunit/languages/LanguageLvTest.php +++ /dev/null @@ -1,39 +0,0 @@ -lang = Language::factory( 'lv' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), #this must be zero form as per CLDR - array( 'one', 1 ), - array( 'other', 11 ), - array( 'one', 21 ), - array( 'other', 411 ), - array( 'other', 12.345 ), - array( 'other', 20 ), - array( 'one', 31 ), - array( 'other', 200 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageMgTest.php b/tests/phpunit/languages/LanguageMgTest.php deleted file mode 100644 index 06b56547..00000000 --- a/tests/phpunit/languages/LanguageMgTest.php +++ /dev/null @@ -1,35 +0,0 @@ -lang = Language::factory( 'mg' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 200 ), - array( 'other', 123.3434 ), - ); - } - -} diff --git a/tests/phpunit/languages/LanguageMkTest.php b/tests/phpunit/languages/LanguageMkTest.php deleted file mode 100644 index cf5ec3d9..00000000 --- a/tests/phpunit/languages/LanguageMkTest.php +++ /dev/null @@ -1,41 +0,0 @@ -lang = Language::factory( 'mk' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 11 ), - array( 'one', 21 ), - array( 'other', 411 ), - array( 'other', 12.345 ), - array( 'other', 20 ), - array( 'one', 31 ), - array( 'other', 200 ), - ); - } - - -} diff --git a/tests/phpunit/languages/LanguageMlTest.php b/tests/phpunit/languages/LanguageMlTest.php deleted file mode 100644 index 8c4b0b2f..00000000 --- a/tests/phpunit/languages/LanguageMlTest.php +++ /dev/null @@ -1,43 +0,0 @@ -lang = Language::factory( 'Ml' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** see bug 29495 */ - /** @dataProvider providerFormatNum*/ - function testFormatNum( $result, $value ) { - $this->assertEquals( $result, $this->lang->formatNum( $value ) ); - } - - function providerFormatNum() { - return array( - array( '12,34,567', '1234567' ), - array( '12,345', '12345' ), - array( '1', '1' ), - array( '123', '123' ) , - array( '1,234', '1234' ), - array( '12,345.56', '12345.56' ), - array( '12,34,56,79,81,23,45,678', '12345679812345678' ), - array( '.12345', '.12345' ), - array( '-12,00,000', '-1200000' ), - array( '-98', '-98' ), - array( '-98', -98 ), - array( '-1,23,45,678', -12345678 ), - array( '', '' ), - array( '', null ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMoTest.php b/tests/phpunit/languages/LanguageMoTest.php deleted file mode 100644 index 533e590f..00000000 --- a/tests/phpunit/languages/LanguageMoTest.php +++ /dev/null @@ -1,43 +0,0 @@ -lang = Language::factory( 'mo' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'few', 101 ), - array( 'few', 119 ), - array( 'other', 120 ), - array( 'other', 200 ), - array( 'few', 201 ), - array( 'few', 219 ), - array( 'other', 220 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageMtTest.php b/tests/phpunit/languages/LanguageMtTest.php deleted file mode 100644 index 421bb388..00000000 --- a/tests/phpunit/languages/LanguageMtTest.php +++ /dev/null @@ -1,72 +0,0 @@ -lang = Language::factory( 'mt' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPluralAllForms */ - function testPluralAllForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralAllForms() { - return array ( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 10 ), - array( 'many', 11 ), - array( 'many', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'other', 101 ), - array( 'few', 102 ), - array( 'few', 110 ), - array( 'many', 111 ), - array( 'many', 119 ), - array( 'other', 120 ), - array( 'other', 201 ), - ); - } - - /** @dataProvider providerPluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralTwoForms() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 19 ), - array( 'many', 20 ), - array( 'many', 99 ), - array( 'many', 100 ), - array( 'many', 101 ), - array( 'many', 102 ), - array( 'many', 110 ), - array( 'many', 111 ), - array( 'many', 119 ), - array( 'many', 120 ), - array( 'many', 201 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageNlTest.php b/tests/phpunit/languages/LanguageNlTest.php deleted file mode 100644 index cf979cd2..00000000 --- a/tests/phpunit/languages/LanguageNlTest.php +++ /dev/null @@ -1,28 +0,0 @@ -lang = Language::factory( 'Nl' ); - } - function tearDown() { - unset( $this->lang ); - } - - function testFormatNum() { - $this->assertEquals( '1.234.567', $this->lang->formatNum( '1234567' ) ); - $this->assertEquals( '12.345', $this->lang->formatNum( '12345' ) ); - $this->assertEquals( '1', $this->lang->formatNum( '1' ) ); - $this->assertEquals( '123', $this->lang->formatNum( '123' ) ); - $this->assertEquals( '1.234', $this->lang->formatNum( '1234' ) ); - $this->assertEquals( '12.345,56', $this->lang->formatNum( '12345.56' ) ); - $this->assertEquals( ',1234556', $this->lang->formatNum( '.1234556' ) ); - } -} diff --git a/tests/phpunit/languages/LanguageNsoTest.php b/tests/phpunit/languages/LanguageNsoTest.php deleted file mode 100644 index ea393628..00000000 --- a/tests/phpunit/languages/LanguageNsoTest.php +++ /dev/null @@ -1,32 +0,0 @@ -lang = Language::factory( 'nso' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguagePlTest.php b/tests/phpunit/languages/LanguagePlTest.php deleted file mode 100644 index e56d4b77..00000000 --- a/tests/phpunit/languages/LanguagePlTest.php +++ /dev/null @@ -1,72 +0,0 @@ -lang = Language::factory( 'pl' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPluralFourForms */ - function testPluralFourForms( $result, $value ) { - $forms = array( 'one', 'few', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralFourForms() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'many', 5 ), - array( 'many', 9 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 21 ), - array( 'few', 22 ), - array( 'few', 23 ), - array( 'few', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - array( 'many', 201 ), - ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - array( 'many', 3 ), - array( 'many', 4 ), - array( 'many', 5 ), - array( 'many', 9 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 21 ), - array( 'many', 22 ), - array( 'many', 23 ), - array( 'many', 24 ), - array( 'many', 25 ), - array( 'many', 200 ), - array( 'many', 201 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageRoTest.php b/tests/phpunit/languages/LanguageRoTest.php deleted file mode 100644 index 5270f6fe..00000000 --- a/tests/phpunit/languages/LanguageRoTest.php +++ /dev/null @@ -1,43 +0,0 @@ -lang = Language::factory( 'ro' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'few', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 19 ), - array( 'other', 20 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'few', 101 ), - array( 'few', 119 ), - array( 'other', 120 ), - array( 'other', 200 ), - array( 'few', 201 ), - array( 'few', 219 ), - array( 'other', 220 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageRuTest.php b/tests/phpunit/languages/LanguageRuTest.php deleted file mode 100644 index 7a1f193b..00000000 --- a/tests/phpunit/languages/LanguageRuTest.php +++ /dev/null @@ -1,54 +0,0 @@ -lang = Language::factory( 'ru' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralFourForms() { - return array ( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providePluralTwoForms() { - return array ( - array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSeTest.php b/tests/phpunit/languages/LanguageSeTest.php deleted file mode 100644 index 065ec29e..00000000 --- a/tests/phpunit/languages/LanguageSeTest.php +++ /dev/null @@ -1,48 +0,0 @@ -lang = Language::factory( 'se' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { - $forms = array( 'one', 'two', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralThreeForms() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 3 ), - ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSgsTest.php b/tests/phpunit/languages/LanguageSgsTest.php deleted file mode 100644 index 931c82f0..00000000 --- a/tests/phpunit/languages/LanguageSgsTest.php +++ /dev/null @@ -1,66 +0,0 @@ -lang = Language::factory( 'Sgs' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePluralAllForms */ - function testPluralAllForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralAllForms() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'other', 3 ), - array( 'many', 10 ), - array( 'many', 11 ), - array( 'many', 12 ), - array( 'many', 19 ), - array( 'other', 20 ), - array( 'many', 100 ), - array( 'one', 101 ), - array( 'many', 111 ), - array( 'many', 112 ), - ); - } - - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralTwoForms() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - array( 'other', 10 ), - array( 'other', 11 ), - array( 'other', 12 ), - array( 'other', 19 ), - array( 'other', 20 ), - array( 'other', 100 ), - array( 'one', 101 ), - array( 'other', 111 ), - array( 'other', 112 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageShTest.php b/tests/phpunit/languages/LanguageShTest.php deleted file mode 100644 index b8169aed..00000000 --- a/tests/phpunit/languages/LanguageShTest.php +++ /dev/null @@ -1,32 +0,0 @@ -lang = Language::factory( 'sh' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'many', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSkTest.php b/tests/phpunit/languages/LanguageSkTest.php deleted file mode 100644 index 4cfd840e..00000000 --- a/tests/phpunit/languages/LanguageSkTest.php +++ /dev/null @@ -1,40 +0,0 @@ -lang = Language::factory( 'sk' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'few', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 11 ), - array( 'other', 20 ), - array( 'other', 25 ), - array( 'other', 200 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSlTest.php b/tests/phpunit/languages/LanguageSlTest.php deleted file mode 100644 index c1f75691..00000000 --- a/tests/phpunit/languages/LanguageSlTest.php +++ /dev/null @@ -1,42 +0,0 @@ -lang = Language::factory( 'sl' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'two', 'few', 'other', 'zero' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'zero', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'other', 5 ), - array( 'other', 99 ), - array( 'other', 100 ), - array( 'one', 101 ), - array( 'two', 102 ), - array( 'few', 103 ), - array( 'one', 201 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSmaTest.php b/tests/phpunit/languages/LanguageSmaTest.php deleted file mode 100644 index b7e72e97..00000000 --- a/tests/phpunit/languages/LanguageSmaTest.php +++ /dev/null @@ -1,48 +0,0 @@ -lang = Language::factory( 'sma' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPluralThreeForms */ - function testPluralThreeForms( $result, $value ) { - $forms = array( 'one', 'two', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPluralThreeForms() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'two', 2 ), - array( 'other', 3 ), - ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'other', 0 ), - array( 'one', 1 ), - array( 'other', 2 ), - array( 'other', 3 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageSrTest.php b/tests/phpunit/languages/LanguageSrTest.php deleted file mode 100644 index d44ecf8e..00000000 --- a/tests/phpunit/languages/LanguageSrTest.php +++ /dev/null @@ -1,223 +0,0 @@ - - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -require_once dirname( __DIR__ ) . '/bootstrap.php'; - -/** Tests for MediaWiki languages/LanguageSr.php */ -class LanguageSrTest extends MediaWikiTestCase { - /* Language object. Initialized before each test */ - private $lang; - - function setUp() { - $this->lang = Language::factory( 'sr' ); - } - function tearDown() { - unset( $this->lang ); - } - - ##### TESTS ####################################################### - - function testEasyConversions( ) { - $this->assertCyrillic( - 'шђчћжШЂЧЋЖ', - 'Cyrillic guessing characters' - ); - $this->assertLatin( - 'šđč枊ĐČĆŽ', - 'Latin guessing characters' - ); - } - - function testMixedConversions() { - $this->assertCyrillic( - 'шђчћжШЂЧЋЖ - šđčćž', - 'Mostly cyrillic characters' - ); - $this->assertLatin( - 'šđč枊ĐČĆŽ - шђчћж', - 'Mostly latin characters' - ); - } - - function testSameAmountOfLatinAndCyrillicGetConverted() { - $this->assertConverted( - '4 latin: šđčć | 4 cyrillic: шђчћ', - 'sr-ec' - ); - $this->assertConverted( - '4 latin: šđčć | 4 cyrillic: шђчћ', - 'sr-el' - ); - } - - /** - * @author Nikola Smolenski - */ - function testConversionToCyrillic() { - //A simple convertion of Latin to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'abvg' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdž', - $this->convertToCyrillic( '-{lj}-ab-{nj}-vg-{dž}-' ) - ); - //A simple convertion of Cyrillic to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'абвг' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdž', - $this->convertToCyrillic( '-{lj}-аб-{nj}-вг-{dž}-' ) - ); - //This text has some Latin, but is recognized as Cyrillic, so it should not be converted - $this->assertEquals( 'abvgшђжчћ', - $this->convertToCyrillic( 'abvgшђжчћ' ) - ); - //Same as above, but assert that -{}-s must be removed - $this->assertEquals( 'љabvgњшђжчћџ', - $this->convertToCyrillic( '-{љ}-abvg-{њ}-шђжчћ-{џ}-' ) - ); - //This text has some Cyrillic, but is recognized as Latin, so it should be converted - $this->assertEquals( 'абвгшђжчћ', - $this->convertToCyrillic( 'абвгšđžčć' ) - ); - //Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабвгnjшђжчћdž', - $this->convertToCyrillic( '-{lj}-абвг-{nj}-šđžčć-{dž}-' ) - ); - // Roman numerals are not converted - $this->assertEquals( 'а I б II в III г IV шђжчћ', - $this->convertToCyrillic( 'a I b II v III g IV šđžčć' ) - ); - } - - function testConversionToLatin() { - //A simple convertion of Latin to Latin - $this->assertEquals( 'abcd', - $this->convertToLatin( 'abcd' ) - ); - //A simple convertion of Cyrillic to Latin - $this->assertEquals( 'abcd', - $this->convertToLatin( 'абцд' ) - ); - //This text has some Latin, but is recognized as Cyrillic, so it should be converted - $this->assertEquals( 'abcdšđžčć', - $this->convertToLatin( 'abcdшђжчћ' ) - ); - //This text has some Cyrillic, but is recognized as Latin, so it should not be converted - $this->assertEquals( 'абцдšđžčć', - $this->convertToLatin( 'абцдšđžčć' ) - ); - } - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralFourForms() { - return array ( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providePluralTwoForms() { - return array ( - array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), - ); - } - - ##### HELPERS ##################################################### - /** - *Wrapper to verify text stay the same after applying conversion - * @param $text string Text to convert - * @param $variant string Language variant 'sr-ec' or 'sr-el' - * @param $msg string Optional message - */ - function assertUnConverted( $text, $variant, $msg = '' ) { - $this->assertEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - /** - * Wrapper to verify a text is different once converted to a variant. - * @param $text string Text to convert - * @param $variant string Language variant 'sr-ec' or 'sr-el' - * @param $msg string Optional message - */ - function assertConverted( $text, $variant, $msg = '' ) { - $this->assertNotEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Verifiy the given Cyrillic text is not converted when using - * using the cyrillic variant and converted to Latin when using - * the Latin variant. - */ - function assertCyrillic( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'sr-ec', $msg ); - $this->assertConverted( $text, 'sr-el', $msg ); - } - /** - * Verifiy the given Latin text is not converted when using - * using the Latin variant and converted to Cyrillic when using - * the Cyrillic variant. - */ - function assertLatin( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'sr-el', $msg ); - $this->assertConverted( $text, 'sr-ec', $msg ); - } - - - /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { - return $this - ->lang - ->mConverter - ->convertTo( - $text, $variant - ); - } - function convertToCyrillic( $text ) { - return $this->convertTo( $text, 'sr-ec' ); - } - function convertToLatin( $text ) { - return $this->convertTo( $text, 'sr-el' ); - } -} diff --git a/tests/phpunit/languages/LanguageTest.php b/tests/phpunit/languages/LanguageTest.php deleted file mode 100644 index 2fa3e292..00000000 --- a/tests/phpunit/languages/LanguageTest.php +++ /dev/null @@ -1,1069 +0,0 @@ -lang = Language::factory( 'en' ); - } - function tearDown() { - unset( $this->lang ); - } - - function testLanguageConvertDoubleWidthToSingleWidth() { - $this->assertEquals( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - $this->lang->normalizeForSearch( - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - ), - 'convertDoubleWidth() with the full alphabet and digits' - ); - } - - /** - * @dataProvider provideFormattableTimes - */ - function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { - $this->assertEquals( $expected, $this->lang->formatTimePeriod( $seconds, $format ), $desc ); - } - - function provideFormattableTimes() { - return array( - array( - 9.45, - array(), - '9.5 s', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.45, - array( 'noabbrevs' => true ), - '9.5 seconds', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.95, - array(), - '10 s', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 9.95, - array( 'noabbrevs' => true ), - '10 seconds', - 'formatTimePeriod() rounding (<10s)' - ), - array( - 59.55, - array(), - '1 min 0 s', - 'formatTimePeriod() rounding (<60s)' - ), - array( - 59.55, - array( 'noabbrevs' => true ), - '1 minute 0 seconds', - 'formatTimePeriod() rounding (<60s)' - ), - array( - 119.55, - array(), - '2 min 0 s', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 119.55, - array( 'noabbrevs' => true ), - '2 minutes 0 seconds', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 3599.55, - array(), - '1 h 0 min 0 s', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 3599.55, - array( 'noabbrevs' => true ), - '1 hour 0 minutes 0 seconds', - 'formatTimePeriod() rounding (<1h)' - ), - array( - 7199.55, - array(), - '2 h 0 min 0 s', - 'formatTimePeriod() rounding (>=1h)' - ), - array( - 7199.55, - array( 'noabbrevs' => true ), - '2 hours 0 minutes 0 seconds', - 'formatTimePeriod() rounding (>=1h)' - ), - array( - 7199.55, - 'avoidseconds', - '2 h 0 min', - 'formatTimePeriod() rounding (>=1h), avoidseconds' - ), - array( - 7199.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 hours 0 minutes', - 'formatTimePeriod() rounding (>=1h), avoidseconds' - ), - array( - 7199.55, - 'avoidminutes', - '2 h 0 min', - 'formatTimePeriod() rounding (>=1h), avoidminutes' - ), - array( - 7199.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '2 hours 0 minutes', - 'formatTimePeriod() rounding (>=1h), avoidminutes' - ), - array( - 172799.55, - 'avoidseconds', - '48 h 0 min', - 'formatTimePeriod() rounding (=48h), avoidseconds' - ), - array( - 172799.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '48 hours 0 minutes', - 'formatTimePeriod() rounding (=48h), avoidseconds' - ), - array( - 259199.55, - 'avoidminutes', - '3 d 0 h', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 259199.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '3 days 0 hours', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 176399.55, - 'avoidseconds', - '2 d 1 h 0 min', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 176399.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 days 1 hour 0 minutes', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 176399.55, - 'avoidminutes', - '2 d 1 h', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 176399.55, - array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), - '2 days 1 hour', - 'formatTimePeriod() rounding (>48h), avoidminutes' - ), - array( - 259199.55, - 'avoidseconds', - '3 d 0 h 0 min', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 259199.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '3 days 0 hours 0 minutes', - 'formatTimePeriod() rounding (>48h), avoidseconds' - ), - array( - 172801.55, - 'avoidseconds', - '2 d 0 h 0 min', - 'formatTimePeriod() rounding, (>48h), avoidseconds' - ), - array( - 172801.55, - array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), - '2 days 0 hours 0 minutes', - 'formatTimePeriod() rounding, (>48h), avoidseconds' - ), - array( - 176460.55, - array(), - '2 d 1 h 1 min 1 s', - 'formatTimePeriod() rounding, recursion, (>48h)' - ), - array( - 176460.55, - array( 'noabbrevs' => true ), - '2 days 1 hour 1 minute 1 second', - 'formatTimePeriod() rounding, recursion, (>48h)' - ), - ); - - } - - function testTruncate() { - $this->assertEquals( - "XXX", - $this->lang->truncate( "1234567890", 0, 'XXX' ), - 'truncate prefix, len 0, small ellipsis' - ); - - $this->assertEquals( - "12345XXX", - $this->lang->truncate( "1234567890", 8, 'XXX' ), - 'truncate prefix, small ellipsis' - ); - - $this->assertEquals( - "123456789", - $this->lang->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ), - 'truncate prefix, large ellipsis' - ); - - $this->assertEquals( - "XXX67890", - $this->lang->truncate( "1234567890", -8, 'XXX' ), - 'truncate suffix, small ellipsis' - ); - - $this->assertEquals( - "123456789", - $this->lang->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ), - 'truncate suffix, large ellipsis' - ); - } - - /** - * @dataProvider provideHTMLTruncateData() - */ - function testTruncateHtml( $len, $ellipsis, $input, $expected ) { - // Actual HTML... - $this->assertEquals( - $expected, - $this->lang->truncateHTML( $input, $len, $ellipsis ) - ); - } - - /** - * Array format is ($len, $ellipsis, $input, $expected) - */ - function provideHTMLTruncateData() { - return array( - array( 0, 'XXX', "1234567890", "XXX" ), - array( 8, 'XXX', "1234567890", "12345XXX" ), - array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ), - array( 2, '***', - '

    ', - '

    ', - ), - array( 2, '***', - '

    123456789

    ', - '

    ***

    ', - ), - array( 2, '***', - '

     23456789

    ', - '

    ***

    ', - ), - array( 3, '***', - '

    123456789

    ', - '

    ***

    ', - ), - array( 4, '***', - '

    123456789

    ', - '

    1***

    ', - ), - array( 5, '***', - '123456789', - '12***', - ), - array( 6, '***', - '

    123456789

    ', - '

    123***

    ', - ), - array( 6, '***', - '

    12 456789

    ', - '

    12 ***

    ', - ), - array( 7, '***', - '123

    456

    789
    ', - '123

    4***

    ', - ), - array( 8, '***', - '
    123456789
    ', - '
    12345***
    ', - ), - array( 9, '***', - '

    123456789

    ', - '

    123456789

    ', - ), - array( 10, '***', - '

    123456789

    ', - '

    123456789

    ', - ), - ); - } - - /** - * Test Language::isValidBuiltInCode() - * @dataProvider provideLanguageCodes - */ - function testBuiltInCodeValidation( $code, $message = '' ) { - $this->assertTrue( - (bool) Language::isValidBuiltInCode( $code ), - "validating code $code $message" - ); - } - - function testBuiltInCodeValidationRejectUnderscore() { - $this->assertFalse( - (bool) Language::isValidBuiltInCode( 'be_tarask' ), - "reject underscore in language code" - ); - } - - function provideLanguageCodes() { - return array( - array( 'fr' , 'Two letters, minor case' ), - array( 'EN' , 'Two letters, upper case' ), - array( 'tyv' , 'Three letters' ), - array( 'tokipona' , 'long language code' ), - array( 'be-tarask', 'With dash' ), - array( 'Zh-classical', 'Begin with upper case, dash' ), - array( 'Be-x-old', 'With extension (two dashes)' ), - ); - } - - /** - * @dataProvider provideSprintfDateSamples - */ - function testSprintfDate( $format, $ts, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->lang->sprintfDate( $format, $ts ), - "sprintfDate('$format', '$ts'): $msg" - ); - } - /** - * bug 33454. sprintfDate should always use UTC. - * @dataProvider provideSprintfDateSamples - */ - function testSprintfDateTZ( $format, $ts, $expected, $msg ) { - $oldTZ = date_default_timezone_get(); - $res = date_default_timezone_set( 'Asia/Seoul' ); - if ( !$res ) { - $this->markTestSkipped( "Error setting Timezone" ); - } - - $this->assertEquals( - $expected, - $this->lang->sprintfDate( $format, $ts ), - "sprintfDate('$format', '$ts'): $msg" - ); - - date_default_timezone_set( $oldTZ ); - } - - function provideSprintfDateSamples() { - return array( - array( - 'xiY', - '20111212000000', - '1390', // note because we're testing English locale we get Latin-standard digits - 'Iranian calendar full year' - ), - array( - 'xiy', - '20111212000000', - '90', - 'Iranian calendar short year' - ), - array( - 'o', - '20120101235000', - '2011', - 'ISO 8601 (week) year' - ), - array( - 'W', - '20120101235000', - '52', - 'Week number' - ), - array( - 'W', - '20120102235000', - '1', - 'Week number' - ), - array( - 'o-\\WW-N', - '20091231235000', - '2009-W53-4', - 'leap week' - ), - // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time - array( - 'Y', - '20120102090705', - '2012', - 'Full year' - ), - array( - 'y', - '20120102090705', - '12', - '2 digit year' - ), - array( - 'L', - '20120102090705', - '1', - 'Leap year' - ), - array( - 'n', - '20120102090705', - '1', - 'Month index, not zero pad' - ), - array( - 'N', - '20120102090705', - '01', - 'Month index. Zero pad' - ), - array( - 'M', - '20120102090705', - 'Jan', - 'Month abbrev' - ), - array( - 'F', - '20120102090705', - 'January', - 'Full month' - ), - array( - 'xg', - '20120102090705', - 'January', - 'Genitive month name (same in EN)' - ), - array( - 'j', - '20120102090705', - '2', - 'Day of month (not zero pad)' - ), - array( - 'd', - '20120102090705', - '02', - 'Day of month (zero-pad)' - ), - array( - 'z', - '20120102090705', - '1', - 'Day of year (zero-indexed)' - ), - array( - 'D', - '20120102090705', - 'Mon', - 'Day of week (abbrev)' - ), - array( - 'l', - '20120102090705', - 'Monday', - 'Full day of week' - ), - array( - 'N', - '20120101090705', - '7', - 'Day of week (Mon=1, Sun=7)' - ), - array( - 'w', - '20120101090705', - '0', - 'Day of week (Sun=0, Sat=6)' - ), - array( - 'N', - '20120102090705', - '1', - 'Day of week' - ), - array( - 'a', - '20120102090705', - 'am', - 'am vs pm' - ), - array( - 'A', - '20120102120000', - 'PM', - 'AM vs PM' - ), - array( - 'a', - '20120102000000', - 'am', - 'AM vs PM' - ), - array( - 'g', - '20120102090705', - '9', - '12 hour, not Zero' - ), - array( - 'h', - '20120102090705', - '09', - '12 hour, zero padded' - ), - array( - 'G', - '20120102090705', - '9', - '24 hour, not zero' - ), - array( - 'H', - '20120102090705', - '09', - '24 hour, zero' - ), - array( - 'H', - '20120102110705', - '11', - '24 hour, zero' - ), - array( - 'i', - '20120102090705', - '07', - 'Minutes' - ), - array( - 's', - '20120102090705', - '05', - 'seconds' - ), - array( - 'U', - '20120102090705', - '1325495225', - 'unix time' - ), - array( - 't', - '20120102090705', - '31', - 'Days in current month' - ), - array( - 'c', - '20120102090705', - '2012-01-02T09:07:05+00:00', - 'ISO 8601 timestamp' - ), - array( - 'r', - '20120102090705', - 'Mon, 02 Jan 2012 09:07:05 +0000', - 'RFC 5322' - ), - array( - 'xmj xmF xmn xmY', - '20120102090705', - '7 Safar 2 1433', - 'Islamic' - ), - array( - 'xij xiF xin xiY', - '20120102090705', - '12 Dey 10 1390', - 'Iranian' - ), - array( - 'xjj xjF xjn xjY', - '20120102090705', - '7 Tevet 4 5772', - 'Hebrew' - ), - array( - 'xjt', - '20120102090705', - '29', - 'Hebrew number of days in month' - ), - array( - 'xjx', - '20120102090705', - 'Tevet', - 'Hebrew genitive month name (No difference in EN)' - ), - array( - 'xkY', - '20120102090705', - '2555', - 'Thai year' - ), - array( - 'xoY', - '20120102090705', - '101', - 'Minguo' - ), - array( - 'xtY', - '20120102090705', - '平成24', - 'nengo' - ), - array( - 'xrxkYY', - '20120102090705', - 'MMDLV2012', - 'Roman numerals' - ), - array( - 'xhxjYY', - '20120102090705', - 'ה\'תשע"ב2012', - 'Hebrew numberals' - ), - array( - 'xnY', - '20120102090705', - '2012', - 'Raw numerals (doesn\'t mean much in EN)' - ), - array( - '[[Y "(yea"\\r)]] \\"xx\\"', - '20120102090705', - '[[2012 (year)]] "x"', - 'Various escaping' - ), - - ); - } - - /** - * @dataProvider provideFormatSizes - */ - function testFormatSize( $size, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->lang->formatSize( $size ), - "formatSize('$size'): $msg" - ); - } - - function provideFormatSizes() { - return array( - array( - 0, - "0 B", - "Zero bytes" - ), - array( - 1024, - "1 KB", - "1 kilobyte" - ), - array( - 1024 * 1024, - "1 MB", - "1,024 megabytes" - ), - array( - 1024 * 1024 * 1024, - "1 GB", - "1 gigabytes" - ), - array( - pow( 1024, 4 ), - "1 TB", - "1 terabyte" - ), - array( - pow( 1024, 5 ), - "1 PB", - "1 petabyte" - ), - array( - pow( 1024, 6 ), - "1 EB", - "1,024 exabyte" - ), - array( - pow( 1024, 7 ), - "1 ZB", - "1 zetabyte" - ), - array( - pow( 1024, 8 ), - "1 YB", - "1 yottabyte" - ), - // How big!? THIS BIG! - ); - } - - /** - * @dataProvider provideFormatBitrate - */ - function testFormatBitrate( $bps, $expected, $msg ) { - $this->assertEquals( - $expected, - $this->lang->formatBitrate( $bps ), - "formatBitrate('$bps'): $msg" - ); - } - - function provideFormatBitrate() { - return array( - array( - 0, - "0 bps", - "0 bits per second" - ), - array( - 999, - "999 bps", - "999 bits per second" - ), - array( - 1000, - "1 kbps", - "1 kilobit per second" - ), - array( - 1000 * 1000, - "1 Mbps", - "1 megabit per second" - ), - array( - pow( 10, 9 ), - "1 Gbps", - "1 gigabit per second" - ), - array( - pow( 10, 12 ), - "1 Tbps", - "1 terabit per second" - ), - array( - pow( 10, 15 ), - "1 Pbps", - "1 petabit per second" - ), - array( - pow( 10, 18 ), - "1 Ebps", - "1 exabit per second" - ), - array( - pow( 10, 21 ), - "1 Zbps", - "1 zetabit per second" - ), - array( - pow( 10, 24 ), - "1 Ybps", - "1 yottabit per second" - ), - array( - pow( 10, 27 ), - "1,000 Ybps", - "1,000 yottabits per second" - ), - ); - } - - - - /** - * @dataProvider provideFormatDuration - */ - function testFormatDuration( $duration, $expected, $intervals = array() ) { - $this->assertEquals( - $expected, - $this->lang->formatDuration( $duration, $intervals ), - "formatDuration('$duration'): $expected" - ); - } - - function provideFormatDuration() { - return array( - array( - 0, - '0 seconds', - ), - array( - 1, - '1 second', - ), - array( - 2, - '2 seconds', - ), - array( - 60, - '1 minute', - ), - array( - 2 * 60, - '2 minutes', - ), - array( - 3600, - '1 hour', - ), - array( - 2 * 3600, - '2 hours', - ), - array( - 24 * 3600, - '1 day', - ), - array( - 2 * 86400, - '2 days', - ), - array( - 365.25 * 86400, // 365.25 * 86400 = 31557600 - '1 year', - ), - array( - 2 * 31557600, - '2 years', - ), - array( - 10 * 31557600, - '1 decade', - ), - array( - 20 * 31557600, - '2 decades', - ), - array( - 100 * 31557600, - '1 century', - ), - array( - 200 * 31557600, - '2 centuries', - ), - array( - 1000 * 31557600, - '1 millennium', - ), - array( - 2000 * 31557600, - '2 millennia', - ), - array( - 9001, - '2 hours, 30 minutes and 1 second' - ), - array( - 3601, - '1 hour and 1 second' - ), - array( - 31557600 + 2 * 86400 + 9000, - '1 year, 2 days, 2 hours and 30 minutes' - ), - array( - 42 * 1000 * 31557600 + 42, - '42 millennia and 42 seconds' - ), - array( - 60, - '60 seconds', - array( 'seconds' ), - ), - array( - 61, - '61 seconds', - array( 'seconds' ), - ), - array( - 1, - '1 second', - array( 'seconds' ), - ), - array( - 31557600 + 2 * 86400 + 9000, - '1 year, 2 days and 150 minutes', - array( 'years', 'days', 'minutes' ), - ), - array( - 42, - '0 days', - array( 'years', 'days' ), - ), - array( - 31557600 + 2 * 86400 + 9000, - '1 year, 2 days and 150 minutes', - array( 'minutes', 'days', 'years' ), - ), - array( - 42, - '0 days', - array( 'days', 'years' ), - ), - ); - } - - /** - * @dataProvider provideCheckTitleEncodingData - */ - function testCheckTitleEncoding( $s ) { - $this->assertEquals( - $s, - $this->lang->checkTitleEncoding($s), - "checkTitleEncoding('$s')" - ); - } - - function provideCheckTitleEncodingData() { - return array ( - array( "" ), - array( "United States of America" ), // 7bit ASCII - array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ), - array( - rawurldecode( - "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn" - ) - ), - // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for - // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding - // uses mb_check_encoding for its test. - array( - rawurldecode( - "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C" - . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C" - . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C" - . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C" - . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C" - . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C" - . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C" - . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C" - . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C" - . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C" - . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C" - . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C" - . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C" - . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis" - ), - ), - array( - rawurldecode( - "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C" - . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C" - . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C" - . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C" - . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou" - . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C" - . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C" - . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C" - . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C" - . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C" - . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C" - . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C" - . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes" - ) - ) - ); - } - - /** - * @dataProvider provideRomanNumeralsData - */ - function testRomanNumerals( $num, $numerals ) { - $this->assertEquals( - $numerals, - Language::romanNumeral( $num ), - "romanNumeral('$num')" - ); - } - - function provideRomanNumeralsData() { - return array( - array( 1, 'I' ), - array( 2, 'II' ), - array( 3, 'III' ), - array( 4, 'IV' ), - array( 5, 'V' ), - array( 6, 'VI' ), - array( 7, 'VII' ), - array( 8, 'VIII' ), - array( 9, 'IX' ), - array( 10, 'X' ), - array( 20, 'XX' ), - array( 30, 'XXX' ), - array( 40, 'XL' ), - array( 49, 'XLIX' ), - array( 50, 'L' ), - array( 60, 'LX' ), - array( 70, 'LXX' ), - array( 80, 'LXXX' ), - array( 90, 'XC' ), - array( 99, 'XCIX' ), - array( 100, 'C' ), - array( 200, 'CC' ), - array( 300, 'CCC' ), - array( 400, 'CD' ), - array( 500, 'D' ), - array( 600, 'DC' ), - array( 700, 'DCC' ), - array( 800, 'DCCC' ), - array( 900, 'CM' ), - array( 999, 'CMXCIX' ), - array( 1000, 'M' ), - array( 1989, 'MCMLXXXIX' ), - array( 2000, 'MM' ), - array( 3000, 'MMM' ), - array( 4000, 'MMMM' ), - array( 5000, 'MMMMM' ), - array( 6000, 'MMMMMM' ), - array( 7000, 'MMMMMMM' ), - array( 8000, 'MMMMMMMM' ), - array( 9000, 'MMMMMMMMM' ), - array( 9999, 'MMMMMMMMMCMXCIX'), - array( 10000, 'MMMMMMMMMM' ), - ); - } -} - diff --git a/tests/phpunit/languages/LanguageTiTest.php b/tests/phpunit/languages/LanguageTiTest.php deleted file mode 100644 index 4bfaa009..00000000 --- a/tests/phpunit/languages/LanguageTiTest.php +++ /dev/null @@ -1,32 +0,0 @@ -lang = Language::factory( 'Ti' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageTlTest.php b/tests/phpunit/languages/LanguageTlTest.php deleted file mode 100644 index a1facd14..00000000 --- a/tests/phpunit/languages/LanguageTlTest.php +++ /dev/null @@ -1,32 +0,0 @@ -lang = Language::factory( 'Tl' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageTrTest.php b/tests/phpunit/languages/LanguageTrTest.php deleted file mode 100644 index bda4c9d9..00000000 --- a/tests/phpunit/languages/LanguageTrTest.php +++ /dev/null @@ -1,68 +0,0 @@ -lang = Language::factory( 'Tr' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** - * See @bug 28040 - * Credits to irc://irc.freenode.net/wikipedia-tr users: - * - berm - * - []LuCkY[] - * - Emperyan - * @see http://en.wikipedia.org/wiki/Dotted_and_dotless_I - * @dataProvider provideDottedAndDotlessI - */ - function testDottedAndDotlessI( $func, $input, $inputCase, $expected ) { - if( $func == 'ucfirst' ) { - $res = $this->lang->ucfirst( $input ); - } elseif( $func == 'lcfirst' ) { - $res = $this->lang->lcfirst( $input ); - } else { - throw new MWException( __METHOD__ . " given an invalid function name '$func'" ); - } - - $msg = "Converting $inputCase case '$input' with $func should give '$expected'"; - - $this->assertEquals( $expected, $res, $msg ); - } - - function provideDottedAndDotlessI() { - return array( - # function, input, input case, expected - # Case changed: - array( 'ucfirst', 'ı', 'lower', 'I' ), - array( 'ucfirst', 'i', 'lower', 'İ' ), - array( 'lcfirst', 'I', 'upper', 'ı' ), - array( 'lcfirst', 'İ', 'upper', 'i' ), - - # Already using the correct case - array( 'ucfirst', 'I', 'upper', 'I' ), - array( 'ucfirst', 'İ', 'upper', 'İ' ), - array( 'lcfirst', 'ı', 'lower', 'ı' ), - array( 'lcfirst', 'i', 'lower', 'i' ), - - # A real example taken from bug 28040 using - # http://tr.wikipedia.org/wiki/%C4%B0Phone - array( 'lcfirst', 'iPhone', 'lower', 'iPhone' ), - - # next case is valid in Turkish but are different words if we - # consider IPhone is English! - array( 'lcfirst', 'IPhone', 'upper', 'ıPhone' ), - - ); - } - -} diff --git a/tests/phpunit/languages/LanguageUkTest.php b/tests/phpunit/languages/LanguageUkTest.php deleted file mode 100644 index 60fafb0d..00000000 --- a/tests/phpunit/languages/LanguageUkTest.php +++ /dev/null @@ -1,54 +0,0 @@ -lang = Language::factory( 'Uk' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providePluralFourForms */ - function testPluralFourForms( $result, $value ) { - $forms = array( 'one', 'few', 'many', 'other' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providePluralFourForms() { - return array ( - array( 'one', 1 ), - array( 'many', 11 ), - array( 'one', 91 ), - array( 'one', 121 ), - array( 'few', 2 ), - array( 'few', 3 ), - array( 'few', 4 ), - array( 'few', 334 ), - array( 'many', 5 ), - array( 'many', 15 ), - array( 'many', 120 ), - ); - } - /** @dataProvider providePluralTwoForms */ - function testPluralTwoForms( $result, $value ) { - $forms = array( 'one', 'several' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - function providePluralTwoForms() { - return array ( - array( 'one', 1 ), - array( 'several', 11 ), - array( 'several', 91 ), - array( 'several', 121 ), - ); - } -} diff --git a/tests/phpunit/languages/LanguageUzTest.php b/tests/phpunit/languages/LanguageUzTest.php deleted file mode 100644 index 72387283..00000000 --- a/tests/phpunit/languages/LanguageUzTest.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @copyright Copyright © 2012, Robin Pepermans - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -require_once dirname( __DIR__ ) . '/bootstrap.php'; - -/** Tests for MediaWiki languages/LanguageUz.php */ -class LanguageUzTest extends MediaWikiTestCase { - /* Language object. Initialized before each test */ - private $lang; - - function setUp() { - $this->lang = Language::factory( 'uz' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** - * @author Nikola Smolenski - */ - function testConversionToCyrillic() { - // A convertion of Latin to Cyrillic - $this->assertEquals( 'абвгғ', - $this->convertToCyrillic( 'abvggʻ' ) - ); - // Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгўоdb', - $this->convertToCyrillic( '-{lj}-ab-{nj}-vgoʻo-{db}-' ) - ); - // A simple convertion of Cyrillic to Cyrillic - $this->assertEquals( 'абвг', - $this->convertToCyrillic( 'абвг' ) - ); - // Same as above, but assert that -{}-s must be removed and not converted - $this->assertEquals( 'ljабnjвгdaž', - $this->convertToCyrillic( '-{lj}-аб-{nj}-вг-{da}-ž' ) - ); - } - - function testConversionToLatin() { - // A simple convertion of Latin to Latin - $this->assertEquals( 'abdef', - $this->convertToLatin( 'abdef' ) - ); - // A convertion of Cyrillic to Latin - $this->assertEquals( 'gʻabtsdOʻQyo', - $this->convertToLatin( 'ғабцдЎҚё' ) - ); - } - - ##### HELPERS ##################################################### - /** - * Wrapper to verify text stay the same after applying conversion - * @param $text string Text to convert - * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' - * @param $msg string Optional message - */ - function assertUnConverted( $text, $variant, $msg = '' ) { - $this->assertEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - /** - * Wrapper to verify a text is different once converted to a variant. - * @param $text string Text to convert - * @param $variant string Language variant 'uz-cyrl' or 'uz-latn' - * @param $msg string Optional message - */ - function assertConverted( $text, $variant, $msg = '' ) { - $this->assertNotEquals( - $text, - $this->convertTo( $text, $variant ), - $msg - ); - } - - /** - * Verifiy the given Cyrillic text is not converted when using - * using the cyrillic variant and converted to Latin when using - * the Latin variant. - */ - function assertCyrillic( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'uz-cyrl', $msg ); - $this->assertConverted( $text, 'uz-latn', $msg ); - } - /** - * Verifiy the given Latin text is not converted when using - * using the Latin variant and converted to Cyrillic when using - * the Cyrillic variant. - */ - function assertLatin( $text, $msg = '' ) { - $this->assertUnConverted( $text, 'uz-latn', $msg ); - $this->assertConverted( $text, 'uz-cyrl', $msg ); - } - - - /** Wrapper for converter::convertTo() method*/ - function convertTo( $text, $variant ) { - return $this->lang->mConverter->convertTo( $text, $variant ); - } - function convertToCyrillic( $text ) { - return $this->convertTo( $text, 'uz-cyrl' ); - } - function convertToLatin( $text ) { - return $this->convertTo( $text, 'uz-latn' ); - } -} diff --git a/tests/phpunit/languages/LanguageWaTest.php b/tests/phpunit/languages/LanguageWaTest.php deleted file mode 100644 index 172f19b9..00000000 --- a/tests/phpunit/languages/LanguageWaTest.php +++ /dev/null @@ -1,32 +0,0 @@ -lang = Language::factory( 'Wa' ); - } - function tearDown() { - unset( $this->lang ); - } - - /** @dataProvider providerPlural */ - function testPlural( $result, $value ) { - $forms = array( 'one', 'many' ); - $this->assertEquals( $result, $this->lang->convertPlural( $value, $forms ) ); - } - - function providerPlural() { - return array ( - array( 'one', 0 ), - array( 'one', 1 ), - array( 'many', 2 ), - ); - } -} diff --git a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php b/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php deleted file mode 100644 index 033164b0..00000000 --- a/tests/phpunit/languages/utils/CLDRPluralRuleEvaluatorTest.php +++ /dev/null @@ -1,95 +0,0 @@ -assertEquals( $expected, $result, $comment ); - } - - /** - * @dataProvider invalidTestCases - * @expectedException CLDRPluralRuleError - */ - function testInvalidRules( $rules, $comment ) { - CLDRPluralRuleEvaluator::evaluate( 1, (array) $rules ); - } - - function validTestCases() { - $tests = array( - # expected, number, rule, comment - array( 0, 'n is 1', 1, 'integer number and is' ), - array( 0, 'n is 1', "1", 'string integer number and is' ), - array( 0, 'n is 1', 1.0, 'float number and is' ), - array( 0, 'n is 1', "1.0", 'string float number and is' ), - array( 1, 'n is 1', 1.1, 'float number and is' ), - array( 1, 'n is 1', 2, 'float number and is' ), - - array( 0, 'n in 1,3,5', 3, '' ), - array( 1, 'n not in 1,3,5', 5, '' ), - - array( 1, 'n in 1,3,5', 2, '' ), - array( 0, 'n not in 1,3,5', 4, '' ), - - array( 0, 'n in 1..3', 2, '' ), - array( 0, 'n in 1..3', 3, 'in is inclusive' ), - array( 1, 'n in 1..3', 0, '' ), - - array( 1, 'n not in 1..3', 2, '' ), - array( 1, 'n not in 1..3', 3, 'in is inclusive' ), - array( 0, 'n not in 1..3', 0, '' ), - - array( 1, 'n is not 1 and n is not 2 and n is not 3', 1, 'and relation' ), - array( 0, 'n is not 1 and n is not 2 and n is not 4', 3, 'and relation' ), - - array( 0, 'n is not 1 or n is 1', 1, 'or relation' ), - array( 1, 'n is 1 or n is 2', 3, 'or relation' ), - - array( 0, 'n is 1', 1, 'extra whitespace' ), - - array( 0, 'n mod 3 is 1', 7, 'mod' ), - array( 0, 'n mod 3 is not 1', 4.3, 'mod with floats' ), - - array( 0, 'n within 1..3', 2, 'within with integer' ), - array( 0, 'n within 1..3', 2.5, 'within with float' ), - array( 0, 'n in 1..3', 2, 'in with integer' ), - array( 1, 'n in 1..3', 2.5, 'in with float' ), - - array( 0, 'n in 3 or n is 4 and n is 5', 3, 'and binds more tightly than or' ), - array( 1, 'n is 3 or n is 4 and n is 5', 4, 'and binds more tightly than or' ), - - array( 0, 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', 24, 'breton rule' ), - array( 1, 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', 25, 'breton rule' ), - - array( 0, 'n within 0..2 and n is not 2', 0, 'french rule' ), - array( 0, 'n within 0..2 and n is not 2', 1, 'french rule' ), - array( 0, 'n within 0..2 and n is not 2', 1.2, 'french rule' ), - array( 1, 'n within 0..2 and n is not 2', 2, 'french rule' ), - - array( 1, 'n in 3..10,13..19', 2, 'scottish rule - ranges with comma' ), - array( 0, 'n in 3..10,13..19', 4, 'scottish rule - ranges with comma' ), - array( 1, 'n in 3..10,13..19', 12.999, 'scottish rule - ranges with comma' ), - array( 0, 'n in 3..10,13..19', 13, 'scottish rule - ranges with comma' ), - - array( 0, '5 mod 3 is n', 2, 'n as result of mod - no need to pass' ), - ); - - return $tests; - } - - function invalidTestCases() { - $tests = array( - array( 'n mod mod 5 is 1', 'mod mod' ), - array( 'n', 'just n' ), - array( 'n is in 5', 'is in' ), - ); - return $tests; - } - -} diff --git a/tests/phpunit/maintenance/DumpTestCase.php b/tests/phpunit/maintenance/DumpTestCase.php deleted file mode 100644 index d1344389..00000000 --- a/tests/phpunit/maintenance/DumpTestCase.php +++ /dev/null @@ -1,352 +0,0 @@ -doEdit( $text, $summary ); - if ( $status->isGood() ) { - $value = $status->getValue(); - $revision = $value['revision']; - $revision_id = $revision->getId(); - $text_id = $revision->getTextId(); - if ( ( $revision_id > 0 ) && ( $text_id > 0 ) ) { - return array( $revision_id, $text_id ); - } - } - throw new MWException( "Could not determine revision id (" . $status->getWikiText() . ")" ); - } - - - /** - * gunzips the given file and stores the result in the original file name - * - * @param $fname string: filename to read the gzipped data from and stored - * the gunzipped data into - */ - protected function gunzip( $fname ) { - $gzipped_contents = file_get_contents( $fname ); - if ( $gzipped_contents === FALSE ) { - $this->fail( "Could not get contents of $fname" ); - } - // We resort to use gzinflate instead of gzdecode, as gzdecode - // need not be available - $contents = gzinflate( substr( $gzipped_contents, 10, -8 ) ); - $this->assertEquals( strlen( $contents ), - file_put_contents( $fname, $contents ), "# bytes written" ); - } - - /** - * Default set up function. - * - * Clears $wgUser, and reports errors from addDBData to PHPUnit - */ - public function setUp() { - global $wgUser; - - parent::setUp(); - - // Check if any Exception is stored for rethrowing from addDBData - // @see self::exceptionFromAddDBData - if ( $this->exceptionFromAddDBData !== null ) { - throw $this->exceptionFromAddDBData; - } - - $wgUser = new User(); - } - - /** - * Checks for test output consisting only of lines containing ETA announcements - */ - function expectETAOutput() { - // Newer PHPUnits require assertion about the output using PHPUnit's own - // expectOutput[...] functions. However, the PHPUnit shipped prediactes - // do not allow to check /each/ line of the output using /readable/ REs. - // So we ... - // - // 1. ... add a dummy output checking to make PHPUnit not complain - // about unchecked test output - $this->expectOutputRegex( '//' ); - - // 2. Do the real output checking on our own. - $lines = explode( "\n", $this->getActualOutput() ); - $this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" ); - $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" ); - $timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]"; - foreach ( $lines as $line ) { - $this->assertRegExp( "/$timestamp_re: .* \(ID [0-9]+\) [0-9]* pages .*, [0-9]* revs .*, ETA/", $line ); - } - } - - - /** - * Step the current XML reader until node end of given name is found. - * - * @param $name string: name of the closing element to look for - * (e.g.: "mediawiki" when looking for ) - * - * @return bool: true iff the end node could be found. false otherwise. - */ - protected function skipToNodeEnd( $name ) { - while ( $this->xml->read() ) { - if ( $this->xml->nodeType == XMLReader::END_ELEMENT && - $this->xml->name == $name ) { - return true; - } - } - return false; - } - - /** - * Step the current XML reader to the first element start after the node - * end of a given name. - * - * @param $name string: name of the closing element to look for - * (e.g.: "mediawiki" when looking for ) - * - * @return bool: true iff new element after the closing of $name could be - * found. false otherwise. - */ - protected function skipPastNodeEnd( $name ) { - $this->assertTrue( $this->skipToNodeEnd( $name ), - "Skipping to end of $name" ); - while ( $this->xml->read() ) { - if ( $this->xml->nodeType == XMLReader::ELEMENT ) { - return true; - } - } - return false; - } - - /** - * Opens an XML file to analyze and optionally skips past siteinfo. - * - * @param $fname string: name of file to analyze - * @param $skip_siteinfo bool: (optional) If true, step the xml reader - * to the first element after - */ - protected function assertDumpStart( $fname, $skip_siteinfo = true ) { - $this->xml = new XMLReader(); - $this->assertTrue( $this->xml->open( $fname ), - "Opening temporary file $fname via XMLReader failed" ); - if ( $skip_siteinfo ) { - $this->assertTrue( $this->skipPastNodeEnd( "siteinfo" ), - "Skipping past end of siteinfo" ); - } - } - - /** - * Asserts that the xml reader is at the final closing tag of an xml file and - * closes the reader. - * - * @param $tag string: (optional) the name of the final tag - * (e.g.: "mediawiki" for ) - */ - protected function assertDumpEnd( $name = "mediawiki" ) { - $this->assertNodeEnd( $name, false ); - if ( $this->xml->read() ) { - $this->skipWhitespace(); - } - $this->assertEquals( $this->xml->nodeType, XMLReader::NONE, - "No proper entity left to parse" ); - $this->xml->close(); - } - - /** - * Steps the xml reader over white space - */ - protected function skipWhitespace() { - $cont = true; - while ( $cont && ( ( $this->xml->nodeType == XMLReader::WHITESPACE ) - || ( $this->xml->nodeType == XMLReader::SIGNIFICANT_WHITESPACE ) ) ) { - $cont = $this->xml->read(); - } - } - - /** - * Asserts that the xml reader is at an element of given name, and optionally - * skips past it. - * - * @param $name string: the name of the element to check for - * (e.g.: "mediawiki" for ) - * @param $skip bool: (optional) if true, skip past the found element - */ - protected function assertNodeStart( $name, $skip = true ) { - $this->assertEquals( $name, $this->xml->name, "Node name" ); - $this->assertEquals( XMLReader::ELEMENT, $this->xml->nodeType, "Node type" ); - if ( $skip ) { - $this->assertTrue( $this->xml->read(), "Skipping past start tag" ); - } - } - - /** - * Asserts that the xml reader is at an closing element of given name, and optionally - * skips past it. - * - * @param $name string: the name of the closing element to check for - * (e.g.: "mediawiki" for ) - * @param $skip bool: (optional) if true, skip past the found element - */ - protected function assertNodeEnd( $name, $skip = true ) { - $this->assertEquals( $name, $this->xml->name, "Node name" ); - $this->assertEquals( XMLReader::END_ELEMENT, $this->xml->nodeType, "Node type" ); - if ( $skip ) { - $this->assertTrue( $this->xml->read(), "Skipping past end tag" ); - } - } - - - /** - * Asserts that the xml reader is at an element of given tag that contains a given text, - * and skips over the element. - * - * @param $name string: the name of the element to check for - * (e.g.: "mediawiki" for ...) - * @param $text string|false: If string, check if it equals the elements text. - * If false, ignore the element's text - * @param $skip_ws bool: (optional) if true, skip past white spaces that trail the - * closing element. - */ - protected function assertTextNode( $name, $text, $skip_ws = true ) { - $this->assertNodeStart( $name ); - - if ( $text !== false ) { - $this->assertEquals( $text, $this->xml->value, "Text of node " . $name ); - } - $this->assertTrue( $this->xml->read(), "Skipping past processed text of " . $name ); - $this->assertNodeEnd( $name ); - - if ( $skip_ws ) { - $this->skipWhitespace(); - } - } - - /** - * Asserts that the xml reader is at the start of a page element and skips over the first - * tags, after checking them. - * - * Besides the opening page element, this function also checks for and skips over the - * title, ns, and id tags. Hence after this function, the xml reader is at the first - * revision of the current page. - * - * @param $id int: id of the page to assert - * @param $ns int: number of namespage to assert - * @param $name string: title of the current page - */ - protected function assertPageStart( $id, $ns, $name ) { - - $this->assertNodeStart( "page" ); - $this->skipWhitespace(); - - $this->assertTextNode( "title", $name ); - $this->assertTextNode( "ns", $ns ); - $this->assertTextNode( "id", $id ); - - } - - /** - * Asserts that the xml reader is at the page's closing element and skips to the next - * element. - */ - protected function assertPageEnd() { - $this->assertNodeEnd( "page" ); - $this->skipWhitespace(); - } - - /** - * Asserts that the xml reader is at a revision and checks its representation before - * skipping over it. - * - * @param $id int: id of the revision - * @param $summary string: summary of the revision - * @param $text_id int: id of the revision's text - * @param $text_bytes int: # of bytes in the revision's text - * @param $text_sha1 string: the base36 SHA-1 of the revision's text - * @param $text string|false: (optional) The revision's string, or false to check for a - * revision stub - * @param $parentid int|false: (optional) id of the parent revision - */ - protected function assertRevision( $id, $summary, $text_id, $text_bytes, $text_sha1, $text = false, $parentid = false ) { - - $this->assertNodeStart( "revision" ); - $this->skipWhitespace(); - - $this->assertTextNode( "id", $id ); - if ( $parentid !== false ) { - $this->assertTextNode( "parentid", $parentid ); - } - $this->assertTextNode( "timestamp", false ); - - $this->assertNodeStart( "contributor" ); - $this->skipWhitespace(); - $this->assertTextNode( "ip", false ); - $this->assertNodeEnd( "contributor" ); - $this->skipWhitespace(); - - $this->assertTextNode( "comment", $summary ); - - $this->assertTextNode( "sha1", $text_sha1 ); - - $this->assertNodeStart( "text", false ); - if ( $text_bytes !== false ) { - $this->assertEquals( $this->xml->getAttribute( "bytes" ), $text_bytes, - "Attribute 'bytes' of revision " . $id ); - } - - if ( $text === false ) { - // Testing for a stub - $this->assertEquals( $this->xml->getAttribute( "id" ), $text_id, - "Text id of revision " . $id ); - $this->assertFalse( $this->xml->hasValue, "Revision has text" ); - $this->assertTrue( $this->xml->read(), "Skipping text start tag" ); - if ( ( $this->xml->nodeType == XMLReader::END_ELEMENT ) - && ( $this->xml->name == "text" ) ) { - - $this->xml->read(); - } - $this->skipWhitespace(); - } else { - // Testing for a real dump - $this->assertTrue( $this->xml->read(), "Skipping text start tag" ); - $this->assertEquals( $text, $this->xml->value, "Text of revision " . $id ); - $this->assertTrue( $this->xml->read(), "Skipping past text" ); - $this->assertNodeEnd( "text" ); - $this->skipWhitespace(); - } - - $this->assertNodeEnd( "revision" ); - $this->skipWhitespace(); - } - -} diff --git a/tests/phpunit/maintenance/MaintenanceTest.php b/tests/phpunit/maintenance/MaintenanceTest.php deleted file mode 100644 index 4a6f08fa..00000000 --- a/tests/phpunit/maintenance/MaintenanceTest.php +++ /dev/null @@ -1,812 +0,0 @@ -shutdownSimulated ) { - $this->testCase->fail( __METHOD__ . " called more than once" ); - } - - // The cleanup action. - $this->outputChanneled( false ); - - // Bookkeeping that we simulated the clean up. - $this->shutdownSimulated = true; - } - - // Note that the "public" here does not change visibility - public function outputChanneled( $msg, $channel = null ) { - if ( $this->shutdownSimulated ) { - if ( $msg !== false ) { - $this->testCase->fail( "Already past simulated shutdown, but msg is " - . "not false. Did the hack in Maintenance.php change? Please " - . "adapt the test case or Maintenance.php" ); - } - - // The current call is the one registered via register_shutdown_function. - // We can safely ignore it, as we simulated this one via simulateShutdown - // before (if we did not, the destructor of this instance will warn about - // it) - return; - } - - return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() ); - } - - /** - * Safety net around register_shutdown_function of Maintenance.php - */ - public function __destruct() { - if ( ( ! $this->shutdownSimulated ) && ( ! $this->testCase->hasFailed() ) ) { - // Someone generated a MaintenanceFixup instance without calling - // simulateShutdown. We'd have to raise a PHPUnit exception to correctly - // flag this illegal usage. However, we are already in a destruktor, which - // would trigger undefined behaviour. Hence, we can only report to the - // error output :( Hopefully people read the PHPUnit output. - fwrite( STDERR, "ERROR! Instance of " . __CLASS__ . " destructed without " - . "calling simulateShutdown method. Call simulateShutdown on the " - . "instance before it gets destructed." ); - } - - // The following guard is required, as PHP does not offer default destructors :( - if ( is_callable( "parent::__destruct" ) ) { - parent::__destruct(); - } - } - - public function __construct( MediaWikiTestCase $testCase ) { - parent::__construct(); - $this->testCase = $testCase; - } - - - - // --- Making protected functions visible for test - - public function output( $out, $channel = null ) { - // Just to make PHP not nag about signature mismatches, we copied - // Maintenance::output signature. However, we do not use (or rely on) - // those variables. Instead we pass to Maintenance::output whatever we - // receive at runtime. - return call_user_func_array ( array( "parent", __FUNCTION__ ), func_get_args() ); - } - - - - // --- Requirements for getting instance of abstract class - - public function execute() { - $this->testCase->fail( __METHOD__ . " called unexpectedly" ); - } - -} - -class MaintenanceTest extends MediaWikiTestCase { - - - /** - * The main Maintenance instance that is used for testing. - * - * @var MaintenanceFixup - */ - private $m; - - - protected function setUp() { - parent::setUp(); - $this->m = new MaintenanceFixup( $this ); - } - - - /** - * asserts the output before and after simulating shutdown - * - * This function simulates shutdown of self::m. - * - * @param $preShutdownOutput string: expected output before simulating shutdown - * @param $expectNLAppending bool: Whether or not shutdown simulation is expected - * to add a newline to the output. If false, $preShutdownOutput is the - * expected output after shutdown simulation. Otherwise, - * $preShutdownOutput with an appended newline is the expected output - * after shutdown simulation. - */ - private function assertOutputPrePostShutdown( $preShutdownOutput, $expectNLAppending ) { - - $this->assertEquals( $preShutdownOutput, $this->getActualOutput(), - "Output before shutdown simulation" ); - - $this->m->simulateShutdown(); - - $postShutdownOutput = $preShutdownOutput . ( $expectNLAppending ? "\n" : "" ); - $this->expectOutputString( $postShutdownOutput ); - } - - - // Although the following tests do not seem to be too consistent (compare for - // example the newlines within the test.*StringString tests, or the - // test.*Intermittent.* tests), the objective of these tests is not to describe - // consistent behaviour, but rather currently existing behaviour. - - - function testOutputEmpty() { - $this->m->output( "" ); - $this->assertOutputPrePostShutdown( "", False ); - } - - function testOutputString() { - $this->m->output( "foo" ); - $this->assertOutputPrePostShutdown( "foo", False ); - } - - function testOutputStringString() { - $this->m->output( "foo" ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputStringNL() { - $this->m->output( "foo\n" ); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testOutputStringNLNL() { - $this->m->output( "foo\n\n" ); - $this->assertOutputPrePostShutdown( "foo\n\n", False ); - } - - function testOutputStringNLString() { - $this->m->output( "foo\nbar" ); - $this->assertOutputPrePostShutdown( "foo\nbar", False ); - } - - function testOutputStringNLStringNL() { - $this->m->output( "foo\nbar\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputStringNLStringNLLinewise() { - $this->m->output( "foo\n" ); - $this->m->output( "bar\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputStringNLStringNLArbitrary() { - $this->m->output( "" ); - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "\n" ); - $this->m->output( "ba" ); - $this->m->output( "" ); - $this->m->output( "r\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputStringNLStringNLArbitraryAgain() { - $this->m->output( "" ); - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "\nb" ); - $this->m->output( "a" ); - $this->m->output( "" ); - $this->m->output( "r\n" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputWNullChannelEmpty() { - $this->m->output( "", null ); - $this->assertOutputPrePostShutdown( "", False ); - } - - function testOutputWNullChannelString() { - $this->m->output( "foo", null ); - $this->assertOutputPrePostShutdown( "foo", False ); - } - - function testOutputWNullChannelStringString() { - $this->m->output( "foo", null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputWNullChannelStringNL() { - $this->m->output( "foo\n", null ); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testOutputWNullChannelStringNLNL() { - $this->m->output( "foo\n\n", null ); - $this->assertOutputPrePostShutdown( "foo\n\n", False ); - } - - function testOutputWNullChannelStringNLString() { - $this->m->output( "foo\nbar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar", False ); - } - - function testOutputWNullChannelStringNLStringNL() { - $this->m->output( "foo\nbar\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputWNullChannelStringNLStringNLLinewise() { - $this->m->output( "foo\n", null ); - $this->m->output( "bar\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputWNullChannelStringNLStringNLArbitrary() { - $this->m->output( "", null ); - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "\n", null ); - $this->m->output( "ba", null ); - $this->m->output( "", null ); - $this->m->output( "r\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputWNullChannelStringNLStringNLArbitraryAgain() { - $this->m->output( "", null ); - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "\nb", null ); - $this->m->output( "a", null ); - $this->m->output( "", null ); - $this->m->output( "r\n", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputWChannelString() { - $this->m->output( "foo", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", True ); - } - - function testOutputWChannelStringNL() { - $this->m->output( "foo\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", True ); - } - - function testOutputWChannelStringNLNL() { - // If this test fails, note that output takes strings with double line - // endings (although output's implementation in this situation calls - // outputChanneled with a string ending in a nl ... which is not allowed - // according to the documentation of outputChanneled) - $this->m->output( "foo\n\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\n", True ); - } - - function testOutputWChannelStringNLString() { - $this->m->output( "foo\nbar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputWChannelStringNLStringNL() { - $this->m->output( "foo\nbar\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputWChannelStringNLStringNLLinewise() { - $this->m->output( "foo\n", "bazChannel" ); - $this->m->output( "bar\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - function testOutputWChannelStringNLStringNLArbitrary() { - $this->m->output( "", "bazChannel" ); - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "\n", "bazChannel" ); - $this->m->output( "ba", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "r\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - function testOutputWChannelStringNLStringNLArbitraryAgain() { - $this->m->output( "", "bazChannel" ); - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "\nb", "bazChannel" ); - $this->m->output( "a", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "r\n", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputWMultipleChannelsChannelChange() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->m->output( "qux", "quuxChannel" ); - $this->m->output( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True ); - } - - function testOutputWMultipleChannelsChannelChangeNL() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar\n", "bazChannel" ); - $this->m->output( "qux\n", "quuxChannel" ); - $this->m->output( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True ); - } - - function testOutputWAndWOChannelStringStartWO() { - $this->m->output( "foo" ); - $this->m->output( "bar", "bazChannel" ); - $this->m->output( "qux" ); - $this->m->output( "quux", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nquxquux", True ); - } - - function testOutputWAndWOChannelStringStartW() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "bar" ); - $this->m->output( "qux", "bazChannel" ); - $this->m->output( "quux" ); - $this->assertOutputPrePostShutdown( "foo\nbarqux\nquux", False ); - } - - function testOutputWChannelTypeSwitch() { - $this->m->output( "foo", 1 ); - $this->m->output( "bar", 1.0 ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputIntermittentEmpty() { - $this->m->output( "foo" ); - $this->m->output( "" ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputIntermittentFalse() { - $this->m->output( "foo" ); - $this->m->output( false ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputIntermittentFalseAfterOtherChannel() { - $this->m->output( "qux", "quuxChannel" ); - $this->m->output( "foo" ); - $this->m->output( false ); - $this->m->output( "bar" ); - $this->assertOutputPrePostShutdown( "qux\nfoobar", False ); - } - - function testOutputWNullChannelIntermittentEmpty() { - $this->m->output( "foo", null ); - $this->m->output( "", null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputWNullChannelIntermittentFalse() { - $this->m->output( "foo", null ); - $this->m->output( false, null ); - $this->m->output( "bar", null ); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testOutputWChannelIntermittentEmpty() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( "", "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - function testOutputWChannelIntermittentFalse() { - $this->m->output( "foo", "bazChannel" ); - $this->m->output( false, "bazChannel" ); - $this->m->output( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - // Note that (per documentation) outputChanneled does take strings that end - // in \n, hence we do not test such strings. - - function testOutputChanneledEmpty() { - $this->m->outputChanneled( "" ); - $this->assertOutputPrePostShutdown( "\n", False ); - } - - function testOutputChanneledString() { - $this->m->outputChanneled( "foo" ); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testOutputChanneledStringString() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledStringNLString() { - $this->m->outputChanneled( "foo\nbar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "\nb" ); - $this->m->outputChanneled( "a" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "r" ); - $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", False ); - } - - function testOutputChanneledWNullChannelEmpty() { - $this->m->outputChanneled( "", null ); - $this->assertOutputPrePostShutdown( "\n", False ); - } - - function testOutputChanneledWNullChannelString() { - $this->m->outputChanneled( "foo", null ); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testOutputChanneledWNullChannelStringString() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledWNullChannelStringNLString() { - $this->m->outputChanneled( "foo\nbar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledWNullChannelStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "\nb", null ); - $this->m->outputChanneled( "a", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "r", null ); - $this->assertOutputPrePostShutdown( "\nfoo\n\n\nb\na\n\nr\n", False ); - } - - function testOutputChanneledWChannelString() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo", True ); - } - - function testOutputChanneledWChannelStringNLString() { - $this->m->outputChanneled( "foo\nbar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputChanneledWChannelStringString() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - function testOutputChanneledWChannelStringNLStringNLArbitraryAgain() { - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "\nb", "bazChannel" ); - $this->m->outputChanneled( "a", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "r", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputChanneledWMultipleChannelsChannelChange() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->m->outputChanneled( "qux", "quuxChannel" ); - $this->m->outputChanneled( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar\nqux\ncorge", True ); - } - - function testOutputChanneledWMultipleChannelsChannelChangeEnclosedNull() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", null ); - $this->m->outputChanneled( "qux", null ); - $this->m->outputChanneled( "corge", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", True ); - } - - function testOutputChanneledWMultipleChannelsChannelAfterNullChange() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar", null ); - $this->m->outputChanneled( "qux", null ); - $this->m->outputChanneled( "corge", "quuxChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\ncorge", True ); - } - - function testOutputChanneledWAndWOChannelStringStartWO() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->m->outputChanneled( "qux" ); - $this->m->outputChanneled( "quux", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux", True ); - } - - function testOutputChanneledWAndWOChannelStringStartW() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "bar" ); - $this->m->outputChanneled( "qux", "bazChannel" ); - $this->m->outputChanneled( "quux" ); - $this->assertOutputPrePostShutdown( "foo\nbar\nqux\nquux\n", False ); - } - - function testOutputChanneledWChannelTypeSwitch() { - $this->m->outputChanneled( "foo", 1 ); - $this->m->outputChanneled( "bar", 1.0 ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testOutputChanneledWOChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( "" ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\n\nbar\n", False ); - } - - function testOutputChanneledWOChannelIntermittentFalse() { - $this->m->outputChanneled( "foo" ); - $this->m->outputChanneled( false ); - $this->m->outputChanneled( "bar" ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledWNullChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( "", null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\n\nbar\n", False ); - } - - function testOutputChanneledWNullChannelIntermittentFalse() { - $this->m->outputChanneled( "foo", null ); - $this->m->outputChanneled( false, null ); - $this->m->outputChanneled( "bar", null ); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testOutputChanneledWChannelIntermittentEmpty() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( "", "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foobar", True ); - } - - function testOutputChanneledWChannelIntermittentFalse() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->outputChanneled( false, "bazChannel" ); - $this->m->outputChanneled( "bar", "bazChannel" ); - $this->assertOutputPrePostShutdown( "foo\nbar", True ); - } - - function testCleanupChanneledClean() { - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "", False ); - } - - function testCleanupChanneledAfterOutput() { - $this->m->output( "foo" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo", False ); - } - - function testCleanupChanneledAfterOutputWNullChannel() { - $this->m->output( "foo", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo", False ); - } - - function testCleanupChanneledAfterOutputWChannel() { - $this->m->output( "foo", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterNLOutput() { - $this->m->output( "foo\n" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterNLOutputWNullChannel() { - $this->m->output( "foo\n", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterNLOutputWChannel() { - $this->m->output( "foo\n", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterOutputChanneledWOChannel() { - $this->m->outputChanneled( "foo" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterOutputChanneledWNullChannel() { - $this->m->outputChanneled( "foo", null ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testCleanupChanneledAfterOutputChanneledWChannel() { - $this->m->outputChanneled( "foo", "bazChannel" ); - $this->m->cleanupChanneled(); - $this->assertOutputPrePostShutdown( "foo\n", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutput() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo" ); - $m2->output( "bar" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWNullChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo", null ); - $m2->output( "bar", null ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo", "bazChannel" ); - $m2->output( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", True ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWNullChannelNL() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo\n", null ); - $m2->output( "bar\n", null ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutputWChannelNL() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->output( "foo\n", "bazChannel" ); - $m2->output( "bar\n", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", True ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneled() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo" ); - $m2->outputChanneled( "bar" ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneledWNullChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", null ); - $m2->outputChanneled( "bar", null ); - - $this->assertEquals( "foo\nbar\n", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foo\nbar\n", False ); - } - - function testMultipleMaintenanceObjectsInteractionOutputChanneledWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", "bazChannel" ); - $m2->outputChanneled( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before shutdown simulation (m2)" ); - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n", True ); - } - - function testMultipleMaintenanceObjectsInteractionCleanupChanneledWChannel() { - $m2 = new MaintenanceFixup( $this ); - - $this->m->outputChanneled( "foo", "bazChannel" ); - $m2->outputChanneled( "bar", "bazChannel" ); - - $this->assertEquals( "foobar", $this->getActualOutput(), - "Output before first cleanup" ); - $this->m->cleanupChanneled(); - $this->assertEquals( "foobar\n", $this->getActualOutput(), - "Output after first cleanup" ); - $m2->cleanupChanneled(); - $this->assertEquals( "foobar\n\n", $this->getActualOutput(), - "Output after second cleanup" ); - - $m2->simulateShutdown(); - $this->assertOutputPrePostShutdown( "foobar\n\n", False ); - } - - -} \ No newline at end of file diff --git a/tests/phpunit/maintenance/backupPrefetchTest.php b/tests/phpunit/maintenance/backupPrefetchTest.php deleted file mode 100644 index 8ff85574..00000000 --- a/tests/phpunit/maintenance/backupPrefetchTest.php +++ /dev/null @@ -1,270 +0,0 @@ -dump !== null ) { - $this->dump->close(); - } - - // Bug 37458, parent teardown need to be done after closing the - // dump or it might cause some permissions errors. - parent::tearDown(); - } - - /** - * asserts that a prefetch yields an expected string - * - * @param $expected string|null: the exepcted result of the prefetch - * @param $page int: the page number to prefetch the text for - * @param $revision int: the revision number to prefetch the text for - */ - private function assertPrefetchEquals( $expected, $page, $revision ) { - $this->assertEquals( $expected, $this->dump->prefetch( $page, $revision ), - "Prefetch of page $page revision $revision" ); - - } - - function testSequential() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeRevisionMissToRevision() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 2, 3 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - } - - function testSynchronizeRevisionMissToPage() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 2, 40 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizePageMiss() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 3, 40 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testPageMissAtEnd() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 6, 40 ); - } - - function testRevisionMissAtEnd() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( null, 4, 40 ); - } - - function testSynchronizePageMissAtStart() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( null, 0, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - function testSynchronizeRevisionMissAtStart() { - $fname = $this->setUpPrefetch(); - $this->dump = new BaseDump( $fname ); - - $this->assertPrefetchEquals( null, 1, -2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - function testSequentialAcrossFiles() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2, 4 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - $this->assertPrefetchEquals( "BackupDumperTestP2Text4 some additional Text", 2, 5 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeSkipAcrossFile() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2 ) ); - $fname3 = $this->setUpPrefetch( array( 4 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 . ";" . $fname3 ); - - $this->assertPrefetchEquals( "BackupDumperTestP1Text1", 1, 1 ); - $this->assertPrefetchEquals( "Talk about BackupDumperTestP1 Text1", 4, 8 ); - } - - function testSynchronizeMissInWholeFirstFile() { - $fname1 = $this->setUpPrefetch( array( 1 ) ); - $fname2 = $this->setUpPrefetch( array( 2 ) ); - $this->dump = new BaseDump( $fname1 . ";" . $fname2 ); - - $this->assertPrefetchEquals( "BackupDumperTestP2Text1", 2, 2 ); - } - - - /** - * Constructs a temporary file that can be used for prefetching - * - * The temporary file is removed by DumpBackup upon tearDown. - * - * @param $requested_pages Array The indices of the page parts that should - * go into the prefetch file. 1,2,4 are available. - * @return String The file name of the created temporary file - */ - private function setUpPrefetch( $requested_pages = array( 1, 2, 4 ) ) { - // The file name, where we store the prepared prefetch file - $fname = $this->getNewTempFile(); - - // The header of every prefetch file - $header = ' - - wikisvn - http://localhost/wiki-svn/index.php/Main_Page - MediaWiki 1.20alpha - first-letter - - Media - Special - - Talk - User - User talk - Wikisvn - Wikisvn talk - File - File talk - MediaWiki - MediaWiki talk - Template - Template talk - Help - Help talk - Category - Category talk - - -'; - - - // An array holding the pages that are available for prefetch - $available_pages = array(); - - // Simple plain page - $available_pages[1] = ' - BackupDumperTestP1 - 0 - 1 - - 1 - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP1Summary1 - 0bolhl6ol7i6x0e7yq91gxgaan39j87 - BackupDumperTestP1Text1 - - -'; - // Page with more than one revisions. Hole in rev ids. - $available_pages[2] = ' - BackupDumperTestP2 - 0 - 2 - - 2 - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary1 - jprywrymfhysqllua29tj3sc7z39dl2 - BackupDumperTestP2Text1 - - - 5 - 2 - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary4 extra - 6o1ciaxa6pybnqprmungwofc4lv00wv - BackupDumperTestP2Text4 some additional Text - - -'; - // Page with id higher than previous id + 1 - $available_pages[4] = ' - Talk:BackupDumperTestP1 - 1 - 4 - - 8 - 2012-04-01T16:46:05Z - - 127.0.0.1 - - Talk BackupDumperTestP1 Summary1 - nktofwzd0tl192k3zfepmlzxoax1lpe - Talk about BackupDumperTestP1 Text1 - - -'; - - // The common ending for all files - $tail = ' -'; - - // Putting together the content of the prefetch files - $content = $header; - foreach ( $requested_pages as $i ) { - $this->assertTrue( array_key_exists( $i, $available_pages ), - "Check for availability of requested page " . $i ); - $content .= $available_pages[ $i ]; - } - $content .= $tail; - - $this->assertEquals( strlen( $content ), file_put_contents( - $fname, $content ), "Length of prepared prefetch" ); - - return $fname; - } - -} diff --git a/tests/phpunit/maintenance/backupTextPassTest.php b/tests/phpunit/maintenance/backupTextPassTest.php deleted file mode 100644 index a0bbadf9..00000000 --- a/tests/phpunit/maintenance/backupTextPassTest.php +++ /dev/null @@ -1,563 +0,0 @@ -tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - try { - // Simple page - $title = Title::newFromText( 'BackupDumperTestP1' ); - $page = WikiPage::factory( $title ); - list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page, - "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" ); - $this->pageId1 = $page->getId(); - - // Page with more than one revision - $title = Title::newFromText( 'BackupDumperTestP2' ); - $page = WikiPage::factory( $title ); - list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page, - "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page, - "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" ); - list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page, - "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" ); - list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page, - "BackupDumperTestP2Text4 some additional Text ", - "BackupDumperTestP2Summary4 extra " ); - $this->pageId2 = $page->getId(); - - // Deleted page. - $title = Title::newFromText( 'BackupDumperTestP3' ); - $page = WikiPage::factory( $title ); - list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page, - "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page, - "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" ); - $this->pageId3 = $page->getId(); - $page->doDeleteArticle( "Testing ;)" ); - - // Page from non-default namespace - $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK ); - $page = WikiPage::factory( $title ); - list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page, - "Talk about BackupDumperTestP1 Text1", - "Talk BackupDumperTestP1 Summary1" ); - $this->pageId4 = $page->getId(); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData in - // DumpTestCase - $this->exceptionFromAddDBData = $e; - } - - } - - public function setUp() { - parent::setUp(); - - // Since we will restrict dumping by page ranges (to allow - // working tests, even if the db gets prepopulated by a base - // class), we have to assert, that the page id are consecutively - // increasing - $this->assertEquals( - array( $this->pageId2, $this->pageId3, $this->pageId4 ), - array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), - "Page ids increasing without holes" ); - - } - - function testPlain() { - // Setting up the dump - $nameStub = $this->setUpStub(); - $nameFull = $this->getNewTempFile(); - $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub, - "--output=file:" . $nameFull ) ); - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking for correctness of the dumped data - $this->assertDumpStart( $nameFull ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testPrefetchPlain() { - // The mapping between ids and text, for the hits of the prefetch mock - $prefetchMap = array( - array( $this->pageId1, $this->revId1_1, "Prefetch_________1Text1" ), - array( $this->pageId2, $this->revId2_3, "Prefetch_________2Text3" ) - ); - - // The mock itself - $prefetchMock = $this->getMock( 'BaseDump', array( 'prefetch' ), array(), '', FALSE ); - $prefetchMock->expects( $this->exactly( 6 ) ) - ->method( 'prefetch' ) - ->will( $this->returnValueMap( $prefetchMap ) ); - - // Setting up of the dump - $nameStub = $this->setUpStub(); - $nameFull = $this->getNewTempFile(); - $dumper = new TextPassDumper( array ( "--stub=file:" - . $nameStub, "--output=file:" . $nameFull ) ); - $dumper->prefetch = $prefetchMock; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking for correctness of the dumped data - $this->assertDumpStart( $nameFull ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - // Prefetch kicks in. This is still the SHA-1 of the original text, - // But the actual text (with different SHA-1) comes from prefetch. - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "Prefetch_________1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - // Prefetch kicks in. This is still the SHA-1 of the original text, - // But the actual text (with different SHA-1) comes from prefetch. - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "Prefetch_________2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - - } - - /** - * Ensures that checkpoint dumps are used and written, by successively increasing the - * stub size and dumping until the duration crosses a threshold. - * - * @param $checkpointFormat string: Either "file" for plain text or "gzip" for gzipped - * checkpoint files. - */ - private function checkpointHelper( $checkpointFormat = "file" ) { - // Getting temporary names - $nameStub = $this->getNewTempFile(); - $nameOutputDir = $this->getNewTempDirectory(); - - $stderr = fopen( 'php://output', 'a' ); - if ( $stderr === FALSE ) { - $this->fail( "Could not open stream for stderr" ); - } - - $iterations = 32; // We'll start with that many iterations of revisions in stub - $lastDuration = 0; - $minDuration = 2; // We want the dump to take at least this many seconds - $checkpointAfter = 0.5; // Generate checkpoint after this many seconds - - - // Until a dump takes at least $minDuration seconds, perform a dump and check - // duration. If the dump did not take long enough increase the iteration - // count, to generate a bigger stub file next time. - while ( $lastDuration < $minDuration ) { - - // Setting up the dump - wfRecursiveRemoveDir( $nameOutputDir ); - $this->assertTrue( wfMkdirParents( $nameOutputDir ), - "Creating temporary output directory " ); - $this->setUpStub( $nameStub, $iterations ); - $dumper = new TextPassDumper( array ( "--stub=file:" . $nameStub, - "--output=" . $checkpointFormat . ":" . $nameOutputDir . "/full", - "--maxtime=1" /*This is in minutes. Fixup is below*/, - "--checkpointfile=checkpoint-%s-%s.xml.gz" ) ); - $dumper->setDb( $this->db ); - $dumper->maxTimeAllowed = $checkpointAfter; // Patching maxTime from 1 minute - $dumper->stderr = $stderr; - - // The actual dump and taking time - $ts_before = microtime( true ); - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - $ts_after = microtime( true ); - $lastDuration = $ts_after - $ts_before; - - // Handling increasing the iteration count for the stubs - if ( $lastDuration < $minDuration ) { - $old_iterations = $iterations; - if ( $lastDuration > 0.2 ) { - // lastDuration is big enough, to allow an educated guess - $factor = ( $minDuration + 0.5 ) / $lastDuration; - if ( ( $factor > 1.1 ) && ( $factor < 100 ) ) { - // educated guess is reasonable - $iterations = (int)( $iterations * $factor ); - } - } - - if ( $old_iterations == $iterations ) { - // Heuristics were not applied, so we just *2. - $iterations *= 2; - } - - $this->assertLessThan( 50000, $iterations, - "Emergency stop against infinitely increasing iteration " - . "count ( last duration: $lastDuration )" ); - } - } - - // The dump (hopefully) did take long enough to produce more than one - // checkpoint file. - // - // We now check all the checkpoint files for validity. - - $files = scandir( $nameOutputDir ); - $this->assertTrue( asort( $files ), "Sorting files in temporary directory" ); - $fileOpened = false; - $lookingForPage = 1; - $checkpointFiles = 0; - - // Each run of the following loop body tries to handle exactly 1 /page/ (not - // iteration of stub content). $i is only increased after having treated page 4. - for ( $i = 0 ; $i < $iterations ; ) { - - // 1. Assuring a file is opened and ready. Skipping across header if - // necessary. - if ( ! $fileOpened ) { - $this->assertNotEmpty( $files, "No more existing dump files, " - . "but not yet all pages found" ); - $fname = array_shift( $files ); - while ( $fname == "." || $fname == ".." ) { - $this->assertNotEmpty( $files, "No more existing dump" - . " files, but not yet all pages found" ); - $fname = array_shift( $files ); - } - if ( $checkpointFormat == "gzip" ) { - $this->gunzip( $nameOutputDir . "/" . $fname ); - } - $this->assertDumpStart( $nameOutputDir . "/" . $fname ); - $fileOpened = true; - $checkpointFiles++; - } - - // 2. Performing a single page check - switch ( $lookingForPage ) { - case 1: - // Page 1 - $this->assertPageStart( $this->pageId1 + $i * self::$numOfPages, NS_MAIN, - "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1 + $i * self::$numOfRevs, "BackupDumperTestP1Summary1", - $this->textId1_1, false, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - $lookingForPage = 2; - break; - - case 2: - // Page 2 - $this->assertPageStart( $this->pageId2 + $i * self::$numOfPages, NS_MAIN, - "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1 + $i * self::$numOfRevs, "BackupDumperTestP2Summary1", - $this->textId2_1, false, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2 + $i * self::$numOfRevs, "BackupDumperTestP2Summary2", - $this->textId2_2, false, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 + $i * self::$numOfRevs ); - $this->assertRevision( $this->revId2_3 + $i * self::$numOfRevs, "BackupDumperTestP2Summary3", - $this->textId2_3, false, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 + $i * self::$numOfRevs ); - $this->assertRevision( $this->revId2_4 + $i * self::$numOfRevs, - "BackupDumperTestP2Summary4 extra", - $this->textId2_4, false, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", - $this->revId2_3 + $i * self::$numOfRevs ); - $this->assertPageEnd(); - - $lookingForPage = 4; - break; - - case 4: - // Page 4 - $this->assertPageStart( $this->pageId4 + $i * self::$numOfPages, NS_TALK, - "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1 + $i * self::$numOfRevs, - "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, false, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $lookingForPage = 1; - - // We dealt with the whole iteration. - $i++; - break; - - default: - $this->fail( "Bad setting for lookingForPage ($lookingForPage)" ); - } - - // 3. Checking for the end of the current checkpoint file - if ( $this->xml->nodeType == XMLReader::END_ELEMENT - && $this->xml->name == "mediawiki" ) { - - $this->assertDumpEnd(); - $fileOpened = false; - } - } - - // Assuring we completely read all files ... - $this->assertFalse( $fileOpened, "Currently read file still open?" ); - $this->assertEmpty( $files, "Remaining unchecked files" ); - - // ... and have dealt with more than one checkpoint file - $this->assertGreaterThan( 1, $checkpointFiles, "# of checkpoint files" ); - - $this->expectETAOutput(); - } - - /** - * @group large - */ - function testCheckpointPlain() { - $this->checkpointHelper(); - } - - /** - * tests for working checkpoint generation in gzip format work. - * - * We keep this test in addition to the simpler self::testCheckpointPlain, as there - * were once problems when the used sinks were DumpPipeOutputs. - * - * xmldumps-backup typically uses bzip2 instead of gzip. However, as bzip2 requires - * PHP extensions, we go for gzip instead, which triggers the same relevant code - * paths while still being testable on more systems. - * - * @group large - */ - function testCheckpointGzip() { - $this->checkpointHelper( "gzip" ); - } - - - /** - * Creates a stub file that is used for testing the text pass of dumps - * - * @param $fname string: (Optional) Absolute name of the file to write - * the stub into. If this parameter is null, a new temporary - * file is generated that is automatically removed upon - * tearDown. - * @param $iterations integer: (Optional) specifies how often the block - * of 3 pages should go into the stub file. The page and - * revision id increase further and further, while the text - * id of the first iteration is reused. The pages and revision - * of iteration > 1 have no corresponding representation in the - * database. - * @return string absolute filename of the stub - */ - private function setUpStub( $fname = null, $iterations = 1 ) { - if ( $fname === null ) { - $fname = $this->getNewTempFile(); - } - $header = ' - - wikisvn - http://localhost/wiki-svn/index.php/Main_Page - MediaWiki 1.20alpha - first-letter - - Media - Special - - Talk - User - User talk - Wikisvn - Wikisvn talk - File - File talk - MediaWiki - MediaWiki talk - Template - Template talk - Help - Help talk - Category - Category talk - - -'; - $tail = ' -'; - - $content = $header; - $iterations = intval( $iterations ); - for ( $i = 0; $i < $iterations; $i++ ) { - - $page1 = ' - BackupDumperTestP1 - 0 - ' . ( $this->pageId1 + $i * self::$numOfPages ) . ' - - ' . ( $this->revId1_1 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP1Summary1 - 0bolhl6ol7i6x0e7yq91gxgaan39j87 - - - -'; - $page2 = ' - BackupDumperTestP2 - 0 - ' . ( $this->pageId2 + $i * self::$numOfPages ) . ' - - ' . ( $this->revId2_1 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary1 - jprywrymfhysqllua29tj3sc7z39dl2 - - - - ' . ( $this->revId2_2 + $i * self::$numOfRevs ) . ' - ' . ( $this->revId2_1 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary2 - b7vj5ks32po5m1z1t1br4o7scdwwy95 - - - - ' . ( $this->revId2_3 + $i * self::$numOfRevs ) . ' - ' . ( $this->revId2_2 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary3 - jfunqmh1ssfb8rs43r19w98k28gg56r - - - - ' . ( $this->revId2_4 + $i * self::$numOfRevs ) . ' - ' . ( $this->revId2_3 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - BackupDumperTestP2Summary4 extra - 6o1ciaxa6pybnqprmungwofc4lv00wv - - - -'; - // page 3 not in stub - - $page4 = ' - Talk:BackupDumperTestP1 - 1 - ' . ( $this->pageId4 + $i * self::$numOfPages ) . ' - - ' . ( $this->revId4_1 + $i * self::$numOfRevs ) . ' - 2012-04-01T16:46:05Z - - 127.0.0.1 - - Talk BackupDumperTestP1 Summary1 - nktofwzd0tl192k3zfepmlzxoax1lpe - - - -'; - $content .= $page1 . $page2 . $page4; - } - $content .= $tail; - $this->assertEquals( strlen( $content ), file_put_contents( - $fname, $content ), "Length of prepared stub" ); - return $fname; - } - -} diff --git a/tests/phpunit/maintenance/backup_LogTest.php b/tests/phpunit/maintenance/backup_LogTest.php deleted file mode 100644 index 8a8dea5a..00000000 --- a/tests/phpunit/maintenance/backup_LogTest.php +++ /dev/null @@ -1,227 +0,0 @@ -setPerformer( $user ); - $logEntry->setTarget( Title::newFromText( $title, $ns ) ); - if ( $comment !== null ) { - $logEntry->setComment( $comment ); - } - if ( $parameters !== null ) { - $logEntry->setParameters( $parameters ); - } - return $logEntry->insert(); - } - - function addDBData() { - $this->tablesUsed[] = 'logging'; - $this->tablesUsed[] = 'user'; - - try { - $user1 = User::newFromName( 'BackupDumperLogUserA' ); - $this->userId1 = $user1->getId(); - if ( $this->userId1 === 0 ) { - $user1->addToDatabase(); - $this->userId1 = $user1->getId(); - } - $this->assertGreaterThan( 0, $this->userId1 ); - - $user2 = User::newFromName( 'BackupDumperLogUserB' ); - $this->userId2 = $user2->getId(); - if ( $this->userId2 === 0 ) { - $user2->addToDatabase(); - $this->userId2 = $user2->getId(); - } - $this->assertGreaterThan( 0, $this->userId2 ); - - $this->logId1 = $this->addLogEntry( 'type', 'subtype', - $user1, NS_MAIN, "PageA" ); - $this->assertGreaterThan( 0, $this->logId1 ); - - $this->logId2 = $this->addLogEntry( 'supress', 'delete', - $user2, NS_TALK, "PageB", "SomeComment" ); - $this->assertGreaterThan( 0, $this->logId2 ); - - $this->logId3 = $this->addLogEntry( 'move', 'delete', - $user2, NS_MAIN, "PageA", "SomeOtherComment", - array( 'key1' => 1, 3 => 'value3' ) ); - $this->assertGreaterThan( 0, $this->logId3 ); - - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData in - // DumpTestCase - $this->exceptionFromAddDBData = $e; - } - - } - - - /** - * asserts that the xml reader is at the beginning of a log entry and skips over - * it while analyzing it. - * - * @param $id int: id of the log entry - * @param $user_name string: user name of the log entry's performer - * @param $user_id int: user id of the log entry 's performer - * @param $comment string|null: comment of the log entry. If null, the comment - * text is ignored. - * @param $type string: type of the log entry - * @param $subtype string: subtype of the log entry - * @param $title string: title of the log entry's target - * @param $parameters array: (optional) unserialized data accompanying the log entry - */ - private function assertLogItem( $id, $user_name, $user_id, $comment, $type, - $subtype, $title, $parameters = array() ) { - - $this->assertNodeStart( "logitem" ); - $this->skipWhitespace(); - - $this->assertTextNode( "id", $id ); - $this->assertTextNode( "timestamp", false ); - - $this->assertNodeStart( "contributor" ); - $this->skipWhitespace(); - $this->assertTextNode( "username", $user_name ); - $this->assertTextNode( "id", $user_id ); - $this->assertNodeEnd( "contributor" ); - $this->skipWhitespace(); - - if ( $comment !== null ) { - $this->assertTextNode( "comment", $comment ); - } - $this->assertTextNode( "type", $type ); - $this->assertTextNode( "action", $subtype ); - $this->assertTextNode( "logtitle", $title ); - - $this->assertNodeStart( "params" ); - $parameters_xml = unserialize( $this->xml->value ); - $this->assertEquals( $parameters, $parameters_xml ); - $this->assertTrue( $this->xml->read(), "Skipping past processed text of params" ); - $this->assertNodeEnd( "params" ); - $this->skipWhitespace(); - - $this->assertNodeEnd( "logitem" ); - $this->skipWhitespace(); - } - - function testPlain () { - global $wgContLang; - - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=file:" . $fname ) ); - $dumper->startId = $this->logId1; - $dumper->endId = $this->logId3 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT ); - - // Analyzing the dumped data - $this->assertDumpStart( $fname ); - - $this->assertLogItem( $this->logId1, "BackupDumperLogUserA", - $this->userId1, null, "type", "subtype", "PageA" ); - - $this->assertNotNull( $wgContLang, "Content language object validation" ); - $namespace = $wgContLang->getNsText( NS_TALK ); - $this->assertInternalType( 'string', $namespace ); - $this->assertGreaterThan( 0, strlen( $namespace ) ); - $this->assertLogItem( $this->logId2, "BackupDumperLogUserB", - $this->userId2, "SomeComment", "supress", "delete", - $namespace . ":PageB" ); - - $this->assertLogItem( $this->logId3, "BackupDumperLogUserB", - $this->userId2, "SomeOtherComment", "move", "delete", - "PageA", array( 'key1' => 1, 3 => 'value3' ) ); - - $this->assertDumpEnd(); - } - - function testXmlDumpsBackupUseCaseLogging() { - global $wgContLang; - - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=gzip:" . $fname, - "--reporting=2" ) ); - $dumper->startId = $this->logId1; - $dumper->endId = $this->logId3 + 1; - $dumper->setDb( $this->db ); - - // xmldumps-backup demands reporting, although this is currently not - // implemented in BackupDumper, when dumping logging data. We - // nevertheless capture the output of the dump process already now, - // to be able to alert (once dumping produces reports) that this test - // needs updates. - $dumper->stderr = fopen( 'php://output', 'a' ); - if ( $dumper->stderr === FALSE ) { - $this->fail( "Could not open stream for stderr" ); - } - - // Performing the dump - $dumper->dump( WikiExporter::LOGS, WikiExporter::TEXT ); - - $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" ); - - // Analyzing the dumped data - $this->gunzip( $fname ); - - $this->assertDumpStart( $fname ); - - $this->assertLogItem( $this->logId1, "BackupDumperLogUserA", - $this->userId1, null, "type", "subtype", "PageA" ); - - $this->assertNotNull( $wgContLang, "Content language object validation" ); - $namespace = $wgContLang->getNsText( NS_TALK ); - $this->assertInternalType( 'string', $namespace ); - $this->assertGreaterThan( 0, strlen( $namespace ) ); - $this->assertLogItem( $this->logId2, "BackupDumperLogUserB", - $this->userId2, "SomeComment", "supress", "delete", - $namespace . ":PageB" ); - - $this->assertLogItem( $this->logId3, "BackupDumperLogUserB", - $this->userId2, "SomeOtherComment", "move", "delete", - "PageA", array( 'key1' => 1, 3 => 'value3' ) ); - - $this->assertDumpEnd(); - - // Currently, no reporting is implemented. Alert via failure, once - // this changes. - // If reporting for log dumps has been implemented, please update - // the following statement to catch good output - $this->expectOutputString( '' ); - } - -} diff --git a/tests/phpunit/maintenance/backup_PageTest.php b/tests/phpunit/maintenance/backup_PageTest.php deleted file mode 100644 index 925e277d..00000000 --- a/tests/phpunit/maintenance/backup_PageTest.php +++ /dev/null @@ -1,389 +0,0 @@ -tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - try { - $title = Title::newFromText( 'BackupDumperTestP1' ); - $page = WikiPage::factory( $title ); - list( $this->revId1_1, $this->textId1_1 ) = $this->addRevision( $page, - "BackupDumperTestP1Text1", "BackupDumperTestP1Summary1" ); - $this->pageId1 = $page->getId(); - - $title = Title::newFromText( 'BackupDumperTestP2' ); - $page = WikiPage::factory( $title ); - list( $this->revId2_1, $this->textId2_1 ) = $this->addRevision( $page, - "BackupDumperTestP2Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId2_2, $this->textId2_2 ) = $this->addRevision( $page, - "BackupDumperTestP2Text2", "BackupDumperTestP2Summary2" ); - list( $this->revId2_3, $this->textId2_3 ) = $this->addRevision( $page, - "BackupDumperTestP2Text3", "BackupDumperTestP2Summary3" ); - list( $this->revId2_4, $this->textId2_4 ) = $this->addRevision( $page, - "BackupDumperTestP2Text4 some additional Text ", - "BackupDumperTestP2Summary4 extra " ); - $this->pageId2 = $page->getId(); - - $title = Title::newFromText( 'BackupDumperTestP3' ); - $page = WikiPage::factory( $title ); - list( $this->revId3_1, $this->textId3_1 ) = $this->addRevision( $page, - "BackupDumperTestP3Text1", "BackupDumperTestP2Summary1" ); - list( $this->revId3_2, $this->textId3_2 ) = $this->addRevision( $page, - "BackupDumperTestP3Text2", "BackupDumperTestP2Summary2" ); - $this->pageId3 = $page->getId(); - $page->doDeleteArticle( "Testing ;)" ); - - $title = Title::newFromText( 'BackupDumperTestP1', NS_TALK ); - $page = WikiPage::factory( $title ); - list( $this->revId4_1, $this->textId4_1 ) = $this->addRevision( $page, - "Talk about BackupDumperTestP1 Text1", - "Talk BackupDumperTestP1 Summary1" ); - $this->pageId4 = $page->getId(); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData in - // DumpTestCase - $this->exceptionFromAddDBData = $e; - } - - } - - public function setUp() { - parent::setUp(); - - // Since we will restrict dumping by page ranges (to allow - // working tests, even if the db gets prepopulated by a base - // class), we have to assert, that the page id are consecutively - // increasing - $this->assertEquals( - array( $this->pageId2, $this->pageId3, $this->pageId4 ), - array( $this->pageId1 + 1, $this->pageId2 + 1, $this->pageId3 + 1 ), - "Page ids increasing without holes" ); - - } - - function testFullTextPlain () { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::TEXT ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87", - "BackupDumperTestP1Text1" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2", - "BackupDumperTestP2Text1" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", - "BackupDumperTestP2Text2", $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", - "BackupDumperTestP2Text3", $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", - "BackupDumperTestP2Text4 some additional Text", $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe", - "Talk about BackupDumperTestP1 Text1" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testFullStubPlain () { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::STUB ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testCurrentStubPlain () { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=file:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB ); - - // Checking the dumped data - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - function testCurrentStubGzip () { - // Preparing the dump - $fname = $this->getNewTempFile(); - $dumper = new BackupDumper( array ( "--output=gzip:" . $fname ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->reporting = false; - $dumper->setDb( $this->db ); - - // Performing the dump - $dumper->dump( WikiExporter::CURRENT, WikiExporter::STUB ); - - // Checking the dumped data - $this->gunzip( $fname ); - $this->assertDumpStart( $fname ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - } - - - - function testXmlDumpsBackupUseCase () { - // xmldumps-backup typically performs a single dump that that writes - // out three files - // * gzipped stubs of everything (meta-history) - // * gzipped stubs of latest revisions of all pages (meta-current) - // * gzipped stubs of latest revisions of all pages of namespage 0 - // (articles) - // - // We reproduce such a setup with our mini fixture, although we omit - // chunks, and all the other gimmicks of xmldumps-backup. - // - $fnameMetaHistory = $this->getNewTempFile(); - $fnameMetaCurrent = $this->getNewTempFile(); - $fnameArticles = $this->getNewTempFile(); - - $dumper = new BackupDumper( array ( "--output=gzip:" . $fnameMetaHistory, - "--output=gzip:" . $fnameMetaCurrent, "--filter=latest", - "--output=gzip:" . $fnameArticles, "--filter=latest", - "--filter=notalk", "--filter=namespace:!NS_USER", - "--reporting=1000" ) ); - $dumper->startId = $this->pageId1; - $dumper->endId = $this->pageId4 + 1; - $dumper->setDb( $this->db ); - - // xmldumps-backup uses reporting. We will not check the exact reported - // message, as they are dependent on the processing power of the used - // computer. We only check that reporting does not crash the dumping - // and that something is reported - $dumper->stderr = fopen( 'php://output', 'a' ); - if ( $dumper->stderr === FALSE ) { - $this->fail( "Could not open stream for stderr" ); - } - - // Performing the dump - $dumper->dump( WikiExporter::FULL, WikiExporter::STUB ); - - $this->assertTrue( fclose( $dumper->stderr ), "Closing stderr handle" ); - - // Checking meta-history ------------------------------------------------- - - $this->gunzip( $fnameMetaHistory ); - $this->assertDumpStart( $fnameMetaHistory ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_1, "BackupDumperTestP2Summary1", - $this->textId2_1, 23, "jprywrymfhysqllua29tj3sc7z39dl2" ); - $this->assertRevision( $this->revId2_2, "BackupDumperTestP2Summary2", - $this->textId2_2, 23, "b7vj5ks32po5m1z1t1br4o7scdwwy95", false, $this->revId2_1 ); - $this->assertRevision( $this->revId2_3, "BackupDumperTestP2Summary3", - $this->textId2_3, 23, "jfunqmh1ssfb8rs43r19w98k28gg56r", false, $this->revId2_2 ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - - // Checking meta-current ------------------------------------------------- - - $this->gunzip( $fnameMetaCurrent ); - $this->assertDumpStart( $fnameMetaCurrent ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - $this->assertPageStart( $this->pageId4, NS_TALK, "Talk:BackupDumperTestP1" ); - $this->assertRevision( $this->revId4_1, "Talk BackupDumperTestP1 Summary1", - $this->textId4_1, 35, "nktofwzd0tl192k3zfepmlzxoax1lpe" ); - $this->assertPageEnd(); - - $this->assertDumpEnd(); - - // Checking articles ------------------------------------------------- - - $this->gunzip( $fnameArticles ); - $this->assertDumpStart( $fnameArticles ); - - // Page 1 - $this->assertPageStart( $this->pageId1, NS_MAIN, "BackupDumperTestP1" ); - $this->assertRevision( $this->revId1_1, "BackupDumperTestP1Summary1", - $this->textId1_1, 23, "0bolhl6ol7i6x0e7yq91gxgaan39j87" ); - $this->assertPageEnd(); - - // Page 2 - $this->assertPageStart( $this->pageId2, NS_MAIN, "BackupDumperTestP2" ); - $this->assertRevision( $this->revId2_4, "BackupDumperTestP2Summary4 extra", - $this->textId2_4, 44, "6o1ciaxa6pybnqprmungwofc4lv00wv", false, $this->revId2_3 ); - $this->assertPageEnd(); - - // Page 3 - // -> Page is marked deleted. Hence not visible - - // Page 4 - // -> Page is not in NS_MAIN. Hence not visible - - $this->assertDumpEnd(); - - $this->expectETAOutput(); - } - - - -} diff --git a/tests/phpunit/maintenance/fetchTextTest.php b/tests/phpunit/maintenance/fetchTextTest.php deleted file mode 100644 index e7ffa01c..00000000 --- a/tests/phpunit/maintenance/fetchTextTest.php +++ /dev/null @@ -1,243 +0,0 @@ - 0 ); - - - - /** - * Data for the fake stdin - * - * @param $stdin String The string to be used instead of stdin - */ - function mockStdin( $stdin ) - { - $this->mockStdinText = $stdin; - $this->mockSetUp = True; - } - - /** - * Gets invocation counters for mocked methods. - * - * @return Array An array, whose keys are function names. The corresponding values - * denote the number of times the function has been invoked. - */ - function mockGetInvocations() - { - return $this->mockInvocations; - } - - // ----------------------------------------------------------------- - // Mocked functions from FetchText follow. - - function getStdin( $len = null ) - { - $this->mockInvocations['getStdin']++; - if ( $len !== null ) { - throw new PHPUnit_Framework_ExpectationFailedException( - "Tried to get stdin with non null parameter" ); - } - - if ( ! $this->mockSetUp ) { - throw new PHPUnit_Framework_ExpectationFailedException( - "Tried to get stdin before setting up rerouting" ); - } - - return fopen( 'data://text/plain,' . $this->mockStdinText, 'r' ); - } - -} - -/** - * TestCase for FetchText - * - * @group Database - * @group Dump - */ -class FetchTextTest extends MediaWikiTestCase { - - // We add 5 Revisions for this test. Their corresponding text id's - // are stored in the following 5 variables. - private $textId1; - private $textId2; - private $textId3; - private $textId4; - private $textId5; - - - /** - * @var Exception|null As the current MediaWikiTestCase::run is not - * robust enough to recover from thrown exceptions directly, we cannot - * throw frow within addDBData, although it would be appropriate. Hence, - * we catch the exception and store it until we are in setUp and may - * finally rethrow the exception without crashing the test suite. - */ - private $exceptionFromAddDBData; - - /** - * @var FetchText the (mocked) FetchText that is to test - */ - private $fetchText; - - /** - * Adds a revision to a page, while returning the resuting text's id - * - * @param $page WikiPage The page to add the revision to - * @param $text String The revisions text - * @param $text String The revisions summare - * - * @throws MWExcepion - */ - private function addRevision( $page, $text, $summary ) { - $status = $page->doEdit( $text, $summary ); - if ( $status->isGood() ) { - $value = $status->getValue(); - $revision = $value['revision']; - $id = $revision->getTextId(); - if ( $id > 0 ) { - return $id; - } - } - throw new MWException( "Could not determine text id" ); - } - - - function addDBData() { - $this->tablesUsed[] = 'page'; - $this->tablesUsed[] = 'revision'; - $this->tablesUsed[] = 'text'; - - try { - $title = Title::newFromText( 'FetchTextTestPage1' ); - $page = WikiPage::factory( $title ); - $this->textId1 = $this->addRevision( $page, "FetchTextTestPage1Text1", "FetchTextTestPage1Summary1" ); - - $title = Title::newFromText( 'FetchTextTestPage2' ); - $page = WikiPage::factory( $title ); - $this->textId2 = $this->addRevision( $page, "FetchTextTestPage2Text1", "FetchTextTestPage2Summary1" ); - $this->textId3 = $this->addRevision( $page, "FetchTextTestPage2Text2", "FetchTextTestPage2Summary2" ); - $this->textId4 = $this->addRevision( $page, "FetchTextTestPage2Text3", "FetchTextTestPage2Summary3" ); - $this->textId5 = $this->addRevision( $page, "FetchTextTestPage2Text4 some additional Text ", "FetchTextTestPage2Summary4 extra " ); - } catch ( Exception $e ) { - // We'd love to pass $e directly. However, ... see - // documentation of exceptionFromAddDBData - $this->exceptionFromAddDBData = $e; - } - } - - - protected function setUp() { - parent::setUp(); - - // Check if any Exception is stored for rethrowing from addDBData - if ( $this->exceptionFromAddDBData !== null ) { - throw $this->exceptionFromAddDBData; - } - - $this->fetchText = new SemiMockedFetchText(); - } - - - /** - * Helper to relate FetchText's input and output - */ - private function assertFilter( $input, $expectedOutput ) { - $this->fetchText->mockStdin( $input ); - $this->fetchText->execute(); - $invocations = $this->fetchText->mockGetInvocations(); - $this->assertEquals( 1, $invocations['getStdin'], - "getStdin invocation counter" ); - $this->expectOutputString( $expectedOutput ); - } - - - - // Instead of the following functions, a data provider would be great. - // However, as data providers are evaluated /before/ addDBData, a data - // provider would not know the required ids. - - function testExistingSimple() { - $this->assertFilter( $this->textId2, - $this->textId2 . "\n23\nFetchTextTestPage2Text1" ); - } - - function testExistingSimpleWithNewline() { - $this->assertFilter( $this->textId2 . "\n", - $this->textId2 . "\n23\nFetchTextTestPage2Text1" ); - } - - function testExistingSeveral() { - $this->assertFilter( "$this->textId1\n$this->textId5\n" - . "$this->textId3\n$this->textId3", - implode( "", array( - $this->textId1 . "\n23\nFetchTextTestPage1Text1", - $this->textId5 . "\n44\nFetchTextTestPage2Text4 " - . "some additional Text", - $this->textId3 . "\n23\nFetchTextTestPage2Text2", - $this->textId3 . "\n23\nFetchTextTestPage2Text2" - ) ) ); - } - - function testEmpty() { - $this->assertFilter( "", null ); - } - - function testNonExisting() { - $this->assertFilter( $this->textId5 + 10, ( $this->textId5 + 10 ) . "\n-1\n" ); - } - - function testNegativeInteger() { - $this->assertFilter( "-42", "-42\n-1\n" ); - } - - function testFloatingPointNumberExisting() { - // float -> int -> revision - $this->assertFilter( $this->textId3 + 0.14159, - $this->textId3 . "\n23\nFetchTextTestPage2Text2" ); - } - - function testFloatingPointNumberNonExisting() { - $this->assertFilter( $this->textId5 + 3.14159, - ( $this->textId5 + 3 ) . "\n-1\n" ); - } - - function testCharacters() { - $this->assertFilter( "abc", "0\n-1\n" ); - } - - function testMix() { - $this->assertFilter( "ab\n" . $this->textId4 . ".5cd\n\nefg\n" . $this->textId2 - . "\n" . $this->textId3, - implode( "", array( - "0\n-1\n", - $this->textId4 . "\n23\nFetchTextTestPage2Text3", - "0\n-1\n", - "0\n-1\n", - $this->textId2 . "\n23\nFetchTextTestPage2Text1", - $this->textId3 . "\n23\nFetchTextTestPage2Text2" - ) ) ); - } - -} diff --git a/tests/phpunit/maintenance/getSlaveServerTest.php b/tests/phpunit/maintenance/getSlaveServerTest.php deleted file mode 100644 index 0b7c758c..00000000 --- a/tests/phpunit/maintenance/getSlaveServerTest.php +++ /dev/null @@ -1,69 +0,0 @@ -db->getType() === 'sqlite' ) { - // for SQLite, only the empty string is a good server name - return ''; - } - - $octet = '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'; - $ip = "(($octet\.){3}$octet)"; - - $label = '([a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)'; - $hostname = "($label(\.$label)*)"; - - return "($ip|$hostname)(:[0-9]{1,5})?"; - } - - function testPlain() { - $gss = new GetSlaveServer(); - $gss->execute(); - - $this->expectOutputRegex( "/^" . self::getServerRE() . "\n$/D" ); - } - - function testXmlDumpsBackupUseCase() { - global $wgDBprefix; - - global $argv; - $argv = array( null, "--globals" ); - - $gss = new GetSlaveServer(); - $gss->loadParamsAndArgs(); - $gss->execute(); - $gss->globals(); - - // The main answer - $output = $this->getActualOutput(); - $firstLineEndPos = strpos( $output,"\n"); - if ( $firstLineEndPos === FALSE ) { - $this->fail( "Could not find end of first line of output" ); - } - $firstLine = substr( $output, 0 , $firstLineEndPos ); - $this->assertRegExp( "/^" . self::getServerRE() . "$/D", - $firstLine, "DB Server" ); - - // xmldumps-backup relies on the wgDBprefix in the output. - $this->expectOutputRegex( "/^[[:space:]]*\[wgDBprefix\][[:space:]]*=> " - . $wgDBprefix . "$/m" ); - } - - -} diff --git a/tests/phpunit/phpunit.php b/tests/phpunit/phpunit.php deleted file mode 100644 index bcbf4ec1..00000000 --- a/tests/phpunit/phpunit.php +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env php -addOption( 'with-phpunitdir' - , 'Directory to include PHPUnit from, for example when using a git fetchout from upstream. Path will be prepended to PHP `include_path`.' - , false # not required - , true # need arg - ); - } - - public function finalSetup() { - parent::finalSetup(); - - global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType; - global $wgLanguageConverterCacheType, $wgUseDatabaseMessages; - global $wgLocaltimezone, $wgLocalisationCacheConf; - global $wgDevelopmentWarnings; - - // wfWarn should cause tests to fail - $wgDevelopmentWarnings = true; - - $wgMainCacheType = CACHE_NONE; - $wgMessageCacheType = CACHE_NONE; - $wgParserCacheType = CACHE_NONE; - $wgLanguageConverterCacheType = CACHE_NONE; - - $wgUseDatabaseMessages = false; # Set for future resets - - // Assume UTC for testing purposes - $wgLocaltimezone = 'UTC'; - - $wgLocalisationCacheConf['storeClass'] = 'LCStore_Null'; - } - - public function execute() { - global $IP; - - # Make sure we have --configuration or PHPUnit might complain - if( !in_array( '--configuration', $_SERVER['argv'] ) ) { - //Hack to eliminate the need to use the Makefile (which sucks ATM) - array_splice( $_SERVER['argv'], 1, 0, - array( '--configuration', $IP . '/tests/phpunit/suite.xml' ) ); - } - - # --with-phpunitdir let us override the default PHPUnit version - if( $phpunitDir = $this->getOption( 'with-phpunitdir' ) ) { - # Sanity checks - if( !is_dir($phpunitDir) ) { - $this->error( "--with-phpunitdir should be set to an existing directory", 1 ); - } - if( !is_readable( $phpunitDir."/PHPUnit/Runner/Version.php" ) ) { - $this->error( "No usable PHPUnit installation in $phpunitDir.\nAborting.\n", 1 ); - } - - # Now prepends provided PHPUnit directory - $this->output( "Will attempt loading PHPUnit from `$phpunitDir`\n" ); - set_include_path( $phpunitDir - . PATH_SEPARATOR . get_include_path() ); - - # Cleanup $args array so the option and its value do not - # pollute PHPUnit - $key = array_search( '--with-phpunitdir', $_SERVER['argv'] ); - unset( $_SERVER['argv'][$key] ); // the option - unset( $_SERVER['argv'][$key+1] ); // its value - $_SERVER['argv'] = array_values( $_SERVER['argv'] ); - - } - } - - public function getDbType() { - return Maintenance::DB_ADMIN; - } -} - -$maintClass = 'PHPUnitMaintClass'; -require( RUN_MAINTENANCE_IF_MAIN ); - -require_once( 'PHPUnit/Runner/Version.php' ); - -if( PHPUnit_Runner_Version::id() !== '@package_version@' - && version_compare( PHPUnit_Runner_Version::id(), '3.6.7', '<' ) ) { - die( 'PHPUnit 3.6.7 or later required, you have ' . PHPUnit_Runner_Version::id() . ".\n" ); -} -require_once( 'PHPUnit/Autoload.php' ); - -require_once( "$IP/tests/TestsAutoLoader.php" ); -MediaWikiPHPUnitCommand::main(); diff --git a/tests/phpunit/run-tests.bat b/tests/phpunit/run-tests.bat deleted file mode 100644 index e6eb3e0c..00000000 --- a/tests/phpunit/run-tests.bat +++ /dev/null @@ -1 +0,0 @@ -php phpunit.php --configuration suite.xml %* diff --git a/tests/phpunit/skins/SideBarTest.php b/tests/phpunit/skins/SideBarTest.php deleted file mode 100644 index 912d7602..00000000 --- a/tests/phpunit/skins/SideBarTest.php +++ /dev/null @@ -1,209 +0,0 @@ -messages array */ - private function initMessagesHref() { - # List of default messages for the sidebar: - $URL_messages = array( - 'mainpage', - 'portal-url', - 'currentevents-url', - 'recentchanges-url', - 'randompage-url', - 'helppage', - ); - - foreach( $URL_messages as $m ) { - $titleName = MessageCache::singleton()->get($m); - $title = Title::newFromText( $titleName ); - $this->messages[$m]['href'] = $title->getLocalURL(); - } - } - - function setUp() { - parent::setUp(); - $this->initMessagesHref(); - $this->skin = new SkinTemplate(); - $this->skin->getContext()->setLanguage( Language::factory( 'en' ) ); - } - function tearDown() { - parent::tearDown(); - $this->skin = null; - } - - /** - * Internal helper to test the sidebar - * @param $expected - * @param $text - * @param $message (Default: '') - */ - private function assertSideBar( $expected, $text, $message = '' ) { - $bar = array(); - $this->skin->addToSidebarPlain( $bar, $text ); - $this->assertEquals( $expected, $bar, $message ); - } - - function testSidebarWithOnlyTwoTitles() { - $this->assertSideBar( - array( - 'Title1' => array(), - 'Title2' => array(), - ), -'* Title1 -* Title2 -' - ); - } - - function testExpandMessages() { - $this->assertSidebar( - array( 'Title' => array( - array( - 'text' => 'Help', - 'href' => $this->messages['helppage']['href'], - 'id' => 'n-help', - 'active' => null - ) - )), -'* Title -** helppage|help -' - ); - } - - function testExternalUrlsRequireADescription() { - $this->assertSidebar( - array( 'Title' => array( - # ** http://www.mediawiki.org/| Home - array( - 'text' => 'Home', - 'href' => 'http://www.mediawiki.org/', - 'id' => 'n-Home', - 'active' => null, - 'rel' => 'nofollow', - ), - # ** http://valid.no.desc.org/ - # ... skipped since it is missing a pipe with a description - )), -'* Title -** http://www.mediawiki.org/| Home -** http://valid.no.desc.org/ -' - - ); - - } - /** - * bug 33321 - Make sure there's a | after transforming. - * @group Database - */ - function testTrickyPipe() { - $this->assertSidebar( - array( 'Title' => array( - # The first 2 are skipped - # Doesn't really test the url properly - # because it will vary with $wgArticlePath et al. - # ** Baz|Fred - array( - 'text' => 'Fred', - 'href' => Title::newFromText( 'Baz' )->getLocalUrl(), - 'id' => 'n-Fred', - 'active' => null, - ), - array( - 'text' => 'title-to-display', - 'href' => Title::newFromText( 'page-to-go-to' )->getLocalUrl(), - 'id' => 'n-title-to-display', - 'active' => null, - ), - )), -'* Title -** {{PAGENAME|Foo}} -** Bar -** Baz|Fred -** {{PLURAL:1|page-to-go-to{{int:pipe-separator/en}}title-to-display|branch not taken}} -' - ); - - } - - - #### Attributes for external links ########################## - private function getAttribs( ) { - # Sidebar text we will use everytime - $text = '* Title -** http://www.mediawiki.org/| Home'; - - $bar = array(); - $this->skin->addToSideBarPlain( $bar, $text ); - - return $bar['Title'][0]; - } - - /** - * Simple test to verify our helper assertAttribs() is functional - * Please note this assume MediaWiki default settings: - * $wgNoFollowLinks = true - * $wgExternalLinkTarget = false - */ - function testTestAttributesAssertionHelper() { - $attribs = $this->getAttribs(); - - $this->assertArrayHasKey( 'rel', $attribs ); - $this->assertEquals( 'nofollow', $attribs['rel'] ); - - $this->assertArrayNotHasKey( 'target', $attribs ); - } - - /** - * Test $wgNoFollowLinks in sidebar - */ - function testRespectWgnofollowlinks() { - global $wgNoFollowLinks; - $saved = $wgNoFollowLinks; - $wgNoFollowLinks = false; - - $attribs = $this->getAttribs(); - $this->assertArrayNotHasKey( 'rel', $attribs, - 'External URL in sidebar do not have rel=nofollow when $wgNoFollowLinks = false' - ); - - // Restore global - $wgNoFollowLinks = $saved; - } - - /** - * Test $wgExternaLinkTarget in sidebar - */ - function testRespectExternallinktarget() { - global $wgExternalLinkTarget; - $saved = $wgExternalLinkTarget; - - $wgExternalLinkTarget = '_blank'; - $attribs = $this->getAttribs(); - $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_blank' ); - - $wgExternalLinkTarget = '_self'; - $attribs = $this->getAttribs(); - $this->assertArrayHasKey( 'target', $attribs ); - $this->assertEquals( $attribs['target'], '_self' ); - - // Restore global - $wgExternalLinkTarget = $saved; - } - -} diff --git a/tests/phpunit/suite.xml b/tests/phpunit/suite.xml deleted file mode 100644 index 56f64477..00000000 --- a/tests/phpunit/suite.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - includes - - - languages - - - skins - - - - maintenance - - - StructureTest.php - - - suites/UploadFromUrlTestSuite.php - - - suites/ExtensionsTestSuite.php - - - - - Utility - Broken - ParserFuzz - Stub - - - diff --git a/tests/phpunit/suites/ExtensionsTestSuite.php b/tests/phpunit/suites/ExtensionsTestSuite.php deleted file mode 100644 index d728807f..00000000 --- a/tests/phpunit/suites/ExtensionsTestSuite.php +++ /dev/null @@ -1,33 +0,0 @@ -addTestFile( $file ); - } - if ( !count( $files ) ) { - $this->addTest( new DummyExtensionsTest( 'testNothing' ) ); - } - } - - public static function suite() { - return new self; - } -} - -/** - * Needed to avoid warnings like 'No tests found in class "ExtensionsTestSuite".' - * when no extensions with tests are used. - */ -class DummyExtensionsTest extends MediaWikiTestCase { - public function testNothing() { - $this->assertTrue( true ); - } -} diff --git a/tests/phpunit/suites/UploadFromUrlTestSuite.php b/tests/phpunit/suites/UploadFromUrlTestSuite.php deleted file mode 100644 index f2638111..00000000 --- a/tests/phpunit/suites/UploadFromUrlTestSuite.php +++ /dev/null @@ -1,204 +0,0 @@ - 'LocalRepo', - 'name' => 'local', - 'url' => 'http://example.com/images', - 'hashLevels' => 2, - 'transformVia404' => false, - 'backend' => new FSFileBackend( array( - 'name' => 'local-backend', - 'lockManager' => 'fsLockManager', - 'containerPaths' => array( - 'local-public' => wfTempDir() . '/test-repo/public', - 'local-thumb' => wfTempDir() . '/test-repo/thumb', - 'local-temp' => wfTempDir() . '/test-repo/temp', - 'local-deleted' => wfTempDir() . '/test-repo/delete', - ) - ) ), - ); - foreach ( $tmpGlobals as $var => $val ) { - if ( array_key_exists( $var, $GLOBALS ) ) { - $this->savedGlobals[$var] = $GLOBALS[$var]; - } - $GLOBALS[$var] = $val; - } - - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - - $wgEnableParserCache = false; - DeferredUpdates::clearPendingUpdates(); - $wgMemc = wfGetMainCache(); - $messageMemc = wfGetMessageCacheStorage(); - $parserMemc = wfGetParserCacheStorage(); - - // $wgContLang = new StubContLang; - $wgUser = new User; - $context = new RequestContext; - $wgLang = $context->getLanguage(); - $wgOut = $context->getOutput(); - $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); - $wgRequest = $context->getRequest(); - - if ( $wgStyleDirectory === false ) { - $wgStyleDirectory = "$IP/skins"; - } - - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - } - - public function tearDown() { - foreach ( $this->savedGlobals as $var => $val ) { - $GLOBALS[$var] = $val; - } - // Restore backends - RepoGroup::destroySingleton(); - FileBackendGroup::destroySingleton(); - - $this->teardownUploadDir( $this->uploadDir ); - } - - private $uploadDir; - private $keepUploads; - - /** - * Remove the dummy uploads directory - */ - private function teardownUploadDir( $dir ) { - if ( $this->keepUploads ) { - return; - } - - // delete the files first, then the dirs. - self::deleteFiles( - array ( - "$dir/3/3a/Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$dir/0/09/Bad.jpg", - ) - ); - - self::deleteDirs( - array ( - "$dir/3/3a", - "$dir/3", - "$dir/thumb/6/65", - "$dir/thumb/6", - "$dir/thumb/3/3a/Foobar.jpg", - "$dir/thumb/3/3a", - "$dir/thumb/3", - - "$dir/0/09/", - "$dir/0/", - - "$dir/thumb", - "$dir", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - foreach ( $files as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); - } - } - } - - /** - * Delete the specified directories, if they exist. Must be empty. - * - * @param $dirs Array: full paths to directories to delete. - */ - private static function deleteDirs( $dirs ) { - foreach ( $dirs as $dir ) { - if ( is_dir( $dir ) ) { - rmdir( $dir ); - } - } - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - private function setupUploadDir() { - global $IP; - - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - wfDebug( "Creating upload directory $dir\n" ); - - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - return $dir; - } - - wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); - - wfMkdirParents( $dir . '/0/09', null, __METHOD__ ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - - return $dir; - } - - public static function suite() { - // Hack to invoke the autoloader required to get phpunit to recognize - // the UploadFromUrlTest class - class_exists( 'UploadFromUrlTest' ); - $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); - return $suite; - } -} diff --git a/tests/qunit/.htaccess b/tests/qunit/.htaccess deleted file mode 100644 index 605d2f4c..00000000 --- a/tests/qunit/.htaccess +++ /dev/null @@ -1 +0,0 @@ -Allow from all diff --git a/tests/qunit/QUnitTestResources.php b/tests/qunit/QUnitTestResources.php deleted file mode 100644 index 59ae73cd..00000000 --- a/tests/qunit/QUnitTestResources.php +++ /dev/null @@ -1,63 +0,0 @@ - array( - 'scripts' => array( - 'tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js', - 'tests/qunit/suites/resources/jquery/jquery.byteLength.test.js', - 'tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js', - 'tests/qunit/suites/resources/jquery/jquery.client.test.js', - 'tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js', - 'tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js', - 'tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js', - 'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js', - 'tests/qunit/suites/resources/jquery/jquery.localize.test.js', - 'tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js', - 'tests/qunit/suites/resources/jquery/jquery.tabIndex.test.js', - 'tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js', - 'tests/qunit/suites/resources/jquery/jquery.textSelection.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.user.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js', - 'tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js', - 'tests/qunit/suites/resources/mediawiki.api/mediawiki.api.parse.test.js', - 'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js', - 'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js', - ), - 'dependencies' => array( - 'jquery.autoEllipsis', - 'jquery.byteLength', - 'jquery.byteLimit', - 'jquery.client', - 'jquery.colorUtil', - 'jquery.delayedBind', - 'jquery.getAttrs', - 'jquery.highlightText', - 'jquery.localize', - 'jquery.mwExtension', - 'jquery.tabIndex', - 'jquery.tablesorter', - 'jquery.textSelection', - 'mediawiki', - 'mediawiki.api', - 'mediawiki.api.parse', - 'mediawiki.jqueryMsg', - 'mediawiki.Title', - 'mediawiki.Uri', - 'mediawiki.user', - 'mediawiki.util', - 'mediawiki.special.recentchanges', - 'mediawiki.language', - 'mediawiki.cldr', - ), - 'position' => 'top', - ) -); diff --git a/tests/qunit/data/callMwLoaderTestCallback.js b/tests/qunit/data/callMwLoaderTestCallback.js deleted file mode 100644 index 3f2ee92f..00000000 --- a/tests/qunit/data/callMwLoaderTestCallback.js +++ /dev/null @@ -1 +0,0 @@ -mw.loader.testCallback(); diff --git a/tests/qunit/data/load.mock.php b/tests/qunit/data/load.mock.php deleted file mode 100644 index 1c189703..00000000 --- a/tests/qunit/data/load.mock.php +++ /dev/null @@ -1,58 +0,0 @@ - " -mw.loader.implement( 'testUsesMissing', function () { - QUnit.ok( false, 'Module test.usesMissing script should not run.'); - QUnit.start(); -}, {}, {}); -", - - 'testUsesNestedMissing' => " -mw.loader.implement( 'testUsesNestedMissing', function () { - QUnit.ok( false, 'Module testUsesNestedMissing script should not run.'); -}, {}, {}); -", -); - -$response = ''; - -// Only support for non-encoded module names, full module names expected -if ( isset( $_GET['modules'] ) ) { - $modules = explode( ',', $_GET['modules'] ); - foreach ( $modules as $module ) { - if ( isset( $moduleImplementations[$module] ) ) { - $response .= $moduleImplementations[$module]; - } else { - $response .= Xml::encodeJsCall( 'mw.loader.state', array( $module, 'missing' ) ); - } - } -} - -echo $response; diff --git a/tests/qunit/data/qunitOkCall.js b/tests/qunit/data/qunitOkCall.js deleted file mode 100644 index 25c42d6a..00000000 --- a/tests/qunit/data/qunitOkCall.js +++ /dev/null @@ -1,2 +0,0 @@ -QUnit.start(); -QUnit.assert.ok( true, 'Successfully loaded!'); diff --git a/tests/qunit/data/styleTest.css.php b/tests/qunit/data/styleTest.css.php deleted file mode 100644 index 1870d5a3..00000000 --- a/tests/qunit/data/styleTest.css.php +++ /dev/null @@ -1,61 +0,0 @@ -" ); -} - -/** - * CompletenessTest - */ -// Adds toggle checkbox to header -QUnit.config.urlConfig.push( { - id: 'completenesstest', - label: 'Run CompletenessTest', - tooltip: 'Run the completeness test' -} ); - -// Initiate when enabled -if ( QUnit.urlParams.completenesstest ) { - - // Return true to ignore - mwTestIgnore = function ( val, tester, funcPath ) { - - // Don't record methods of the properties of constructors, - // to avoid getting into a loop (prototype.constructor.prototype..). - // Since we're therefor skipping any injection for - // "new mw.Foo()", manually set it to true here. - if ( val instanceof mw.Map ) { - tester.methodCallTracker.Map = true; - return true; - } - if ( val instanceof mw.Title ) { - tester.methodCallTracker.Title = true; - return true; - } - - // Don't record methods of the properties of a jQuery object - if ( val instanceof $ ) { - return true; - } - - return false; - }; - - mwTester = new CompletenessTest( mw, mwTestIgnore ); -} - -/** - * Test environment recommended for all QUnit test modules - */ -// Whether to log environment changes to the console -QUnit.config.urlConfig.push( 'mwlogenv' ); - -/** - * Reset mw.config and others to a fresh copy of the live config for each test(), - * and restore it back to the live one afterwards. - * @param localEnv {Object} [optional] - * @example (see test suite at the bottom of this file) - * - */ -QUnit.newMwEnvironment = ( function () { - var log, liveConfig, liveMessages; - - liveConfig = mw.config.values; - liveMessages = mw.messages.values; - - function freshConfigCopy( custom ) { - // "deep=true" is important here. - // Otherwise we just create a new object with values referring to live config. - // e.g. mw.config.set( 'wgFileExtensions', [] ) would not effect liveConfig, - // but mw.config.get( 'wgFileExtensions' ).push( 'png' ) would as the array - // was passed by reference in $.extend's loop. - return $.extend( {}, liveConfig, custom, /*deep=*/true ); - } - - function freshMessagesCopy( custom ) { - return $.extend( {}, liveMessages, custom, /*deep=*/true ); - } - - log = QUnit.urlParams.mwlogenv ? mw.log : function () {}; - - return function ( localEnv ) { - localEnv = $.extend( { - // QUnit - setup: $.noop, - teardown: $.noop, - // MediaWiki - config: {}, - messages: {} - }, localEnv ); - - return { - setup: function () { - log( 'MwEnvironment> SETUP for "' + QUnit.config.current.module - + ': ' + QUnit.config.current.testName + '"' ); - - // Greetings, mock environment! - mw.config.values = freshConfigCopy( localEnv.config ); - mw.messages.values = freshMessagesCopy( localEnv.messages ); - - localEnv.setup(); - }, - - teardown: function () { - log( 'MwEnvironment> TEARDOWN for "' + QUnit.config.current.module - + ': ' + QUnit.config.current.testName + '"' ); - - localEnv.teardown(); - - // Farewell, mock environment! - mw.config.values = liveConfig; - mw.messages.values = liveMessages; - } - }; - }; -}() ); - -// $.when stops as soon as one fails, which makes sense in most -// practical scenarios, but not in a unit test where we really do -// need to wait until all of them are finished. -QUnit.whenPromisesComplete = function () { - var altPromises = []; - - $.each( arguments, function ( i, arg ) { - var alt = $.Deferred(); - altPromises.push( alt ); - - // Whether this one fails or not, forwards it to - // the 'done' (resolve) callback of the alternative promise. - arg.always( alt.resolve ); - }); - - return $.when.apply( $, altPromises ); -}; - -/** - * Add-on assertion helpers - */ -// Define the add-ons -addons = { - - // Expect boolean true - assertTrue: function ( actual, message ) { - QUnit.push( actual === true, actual, true, message ); - }, - - // Expect boolean false - assertFalse: function ( actual, message ) { - QUnit.push( actual === false, actual, false, message ); - }, - - // Expect numerical value less than X - lt: function ( actual, expected, message ) { - QUnit.push( actual < expected, actual, 'less than ' + expected, message ); - }, - - // Expect numerical value less than or equal to X - ltOrEq: function ( actual, expected, message ) { - QUnit.push( actual <= expected, actual, 'less than or equal to ' + expected, message ); - }, - - // Expect numerical value greater than X - gt: function ( actual, expected, message ) { - QUnit.push( actual > expected, actual, 'greater than ' + expected, message ); - }, - - // Expect numerical value greater than or equal to X - gtOrEq: function ( actual, expected, message ) { - QUnit.push( actual >= expected, actual, 'greater than or equal to ' + expected, message ); - } -}; - -$.extend( QUnit.assert, addons ); - -/** - * Small test suite to confirm proper functionality of the utilities and - * initializations in this file. - */ -var envExecCount = 0; -QUnit.module( 'mediawiki.tests.qunit.testrunner', QUnit.newMwEnvironment({ - setup: function () { - envExecCount += 1; - this.mwHtmlLive = mw.html; - mw.html = { - escape: function () { - return 'mocked-' + envExecCount; - } - }; - }, - teardown: function () { - mw.html = this.mwHtmlLive; - }, - config: { - testVar: 'foo' - }, - messages: { - testMsg: 'Foo.' - } -}) ); - -QUnit.test( 'Setup', 3, function ( assert ) { - assert.equal( mw.html.escape( 'foo' ), 'mocked-1', 'extra setup() callback was ran.' ); - assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object applied' ); - assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object applied' ); - - mw.config.set( 'testVar', 'bar' ); - mw.messages.set( 'testMsg', 'Bar.' ); -}); - -QUnit.test( 'Teardown', 3, function ( assert ) { - assert.equal( mw.html.escape( 'foo' ), 'mocked-2', 'extra setup() callback was re-ran.' ); - assert.equal( mw.config.get( 'testVar' ), 'foo', 'config object restored and re-applied after test()' ); - assert.equal( mw.messages.get( 'testMsg' ), 'Foo.', 'messages object restored and re-applied after test()' ); -}); - -QUnit.module( 'mediawiki.tests.qunit.testrunner-after', QUnit.newMwEnvironment() ); - -QUnit.test( 'Teardown', 3, function ( assert ) { - assert.equal( mw.html.escape( '<' ), '<', 'extra teardown() callback was ran.' ); - assert.equal( mw.config.get( 'testVar' ), null, 'config object restored to live in next module()' ); - assert.equal( mw.messages.get( 'testMsg' ), null, 'messages object restored to live in next module()' ); -}); - -}( jQuery, mediaWiki, QUnit ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js b/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js deleted file mode 100644 index 0dee2ef0..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.autoEllipsis.test.js +++ /dev/null @@ -1,52 +0,0 @@ -( function ( mw, $ ) { - -QUnit.module( 'jquery.autoEllipsis', QUnit.newMwEnvironment() ); - -function createWrappedDiv( text, width ) { - var $wrapper = $( '
    ' ).css( 'width', width ); - var $div = $( '
    ' ).text( text ); - $wrapper.append( $div ); - return $wrapper; -} - -function findDivergenceIndex( a, b ) { - var i = 0; - while ( i < a.length && i < b.length && a[i] === b[i] ) { - i++; - } - return i; -} - -QUnit.test( 'Position right', 4, function ( assert ) { - // We need this thing to be visible, so append it to the DOM - var origText = 'This is a really long random string and there is no way it fits in 100 pixels.'; - var $wrapper = createWrappedDiv( origText, '100px' ); - $( '#qunit-fixture' ).append( $wrapper ); - $wrapper.autoEllipsis( { position: 'right' } ); - - // Verify that, and only one, span element was created - var $span = $wrapper.find( '> span' ); - assert.strictEqual( $span.length, 1, 'autoEllipsis wrapped the contents in a span element' ); - - // Check that the text fits by turning on word wrapping - $span.css( 'whiteSpace', 'nowrap' ); - assert.ltOrEq( $span.width(), $span.parent().width(), "Text fits (making the span 'white-space:nowrap' does not make it wider than its parent)" ); - - // Add two characters using scary black magic - var spanText = $span.text(); - var d = findDivergenceIndex( origText, spanText ); - var spanTextNew = spanText.substr( 0, d ) + origText[d] + origText[d] + '...'; - - assert.gt( spanTextNew.length, spanText.length, 'Verify that the new span-length is indeed greater' ); - - // Put this text in the span and verify it doesn't fit - $span.text( spanTextNew ); - // In IE6 width works like min-width, allow IE6's width to be "equal to" - if ( $.browser.msie && Number( $.browser.version ) === 6 ) { - assert.gtOrEq( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more) - IE6: Maybe equal to as well due to width behaving like min-width in IE6' ); - } else { - assert.gt( $span.width(), $span.parent().width(), 'Fit is maximal (adding two characters makes it not fit any more)' ); - } -}); - -}( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js deleted file mode 100644 index a6ddfca6..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.byteLength.test.js +++ /dev/null @@ -1,33 +0,0 @@ -QUnit.module( 'jquery.byteLength', QUnit.newMwEnvironment() ); - -QUnit.test( 'Simple text', 5, function ( assert ) { - var azLc = 'abcdefghijklmnopqrstuvwxyz', - azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', - num = '0123456789', - x = '*', - space = ' '; - - assert.equal( $.byteLength( azLc ), 26, 'Lowercase a-z' ); - assert.equal( $.byteLength( azUc ), 26, 'Uppercase A-Z' ); - assert.equal( $.byteLength( num ), 10, 'Numbers 0-9' ); - assert.equal( $.byteLength( x ), 1, 'An asterisk' ); - assert.equal( $.byteLength( space ), 3, '3 spaces' ); - -} ); - -QUnit.test( 'Special text', 5, function ( assert ) { - // http://en.wikipedia.org/wiki/UTF-8 - var U_0024 = '$', - U_00A2 = '\u00A2', - U_20AC = '\u20AC', - U_024B62 = '\u024B62', - // The normal one doesn't display properly, try the below which is the same - // according to http://www.fileformat.info/info/unicode/char/24B62/index.htm - U_024B62_alt = '\uD852\uDF62'; - - assert.strictEqual( $.byteLength( U_0024 ), 1, 'U+0024: 1 byte. $ (dollar sign)' ); - assert.strictEqual( $.byteLength( U_00A2 ), 2, 'U+00A2: 2 bytes. \u00A2 (cent sign)' ); - assert.strictEqual( $.byteLength( U_20AC ), 3, 'U+20AC: 3 bytes. \u20AC (euro sign)' ); - assert.strictEqual( $.byteLength( U_024B62 ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character)' ); - assert.strictEqual( $.byteLength( U_024B62_alt ), 4, 'U+024B62: 4 bytes. \uD852\uDF62 (a Han character) - alternative method' ); -} ); diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js b/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js deleted file mode 100644 index 4f86eb96..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js +++ /dev/null @@ -1,234 +0,0 @@ -( function ( $, mw ) { - var simpleSample, U_20AC, mbSample; - - QUnit.module( 'jquery.byteLimit', QUnit.newMwEnvironment() ); - - // Simple sample (20 chars, 20 bytes) - simpleSample = '12345678901234567890'; - - // 3 bytes (euro-symbol) - U_20AC = '\u20AC'; - - // Multi-byte sample (22 chars, 26 bytes) - mbSample = '1234567890' + U_20AC + '1234567890' + U_20AC; - - // Basic sendkey-implementation - function addChars( $input, charstr ) { - var c, len; - for ( c = 0, len = charstr.length; c < len; c += 1 ) { - $input - .val( function ( i, val ) { - // Add character to the value - return val + charstr.charAt( c ); - } ) - .trigger( 'change' ); - } - } - - /** - * Test factory for $.fn.byteLimit - * - * @param $input {jQuery} jQuery object in an input element - * @param hasLimit {Boolean} Wether a limit should apply at all - * @param limit {Number} Limit (if used) otherwise undefined - * The limit should be less than 20 (the sample data's length) - */ - function byteLimitTest( options ) { - var opt = $.extend({ - description: '', - $input: null, - sample: '', - hasLimit: false, - expected: '', - limit: null - }, options); - - QUnit.asyncTest( opt.description, opt.hasLimit ? 3 : 2, function ( assert ) { - setTimeout( function () { - var rawVal, fn, effectiveVal; - - opt.$input.appendTo( '#qunit-fixture' ); - - // Simulate pressing keys for each of the sample characters - addChars( opt.$input, opt.sample ); - - rawVal = opt.$input.val(); - fn = opt.$input.data( 'byteLimit.callback' ); - effectiveVal = fn ? fn( rawVal ) : rawVal; - - if ( opt.hasLimit ) { - assert.ltOrEq( - $.byteLength( effectiveVal ), - opt.limit, - 'Prevent keypresses after byteLimit was reached, length never exceeded the limit' - ); - assert.equal( - $.byteLength( rawVal ), - $.byteLength( opt.expected ), - 'Not preventing keypresses too early, length has reached the expected length' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - - } else { - assert.equal( - $.byteLength( effectiveVal ), - $.byteLength( opt.expected ), - 'Unlimited scenarios are not affected, expected length reached' - ); - assert.equal( rawVal, opt.expected, 'New value matches the expected string' ); - } - QUnit.start(); - }, 10 ); - } ); - } - - byteLimitTest({ - description: 'Plain text input', - $input: $( '' ), - sample: simpleSample, - hasLimit: false, - expected: simpleSample - }); - - byteLimitTest({ - description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)', - $input: $( '' ) - .byteLimit(), - sample: simpleSample, - hasLimit: false, - expected: simpleSample - }); - - byteLimitTest({ - description: 'Limit using the maxlength attribute', - $input: $( '' ) - .attr( 'maxlength', '10' ) - .byteLimit(), - sample: simpleSample, - hasLimit: true, - limit: 10, - expected: '1234567890' - }); - - byteLimitTest({ - description: 'Limit using a custom value', - $input: $( '' ) - .byteLimit( 10 ), - sample: simpleSample, - hasLimit: true, - limit: 10, - expected: '1234567890' - }); - - byteLimitTest({ - description: 'Limit using a custom value, overriding maxlength attribute', - $input: $( '' ) - .attr( 'maxlength', '10' ) - .byteLimit( 15 ), - sample: simpleSample, - hasLimit: true, - limit: 15, - expected: '123456789012345' - }); - - byteLimitTest({ - description: 'Limit using a custom value (multibyte)', - $input: $( '' ) - .byteLimit( 14 ), - sample: mbSample, - hasLimit: true, - limit: 14, - expected: '1234567890' + U_20AC + '1' - }); - - byteLimitTest({ - description: 'Limit using a custom value (multibyte) overlapping a byte', - $input: $( '' ) - .byteLimit( 12 ), - sample: mbSample, - hasLimit: true, - limit: 12, - expected: '1234567890' + '12' - }); - - byteLimitTest({ - description: 'Pass the limit and a callback as input filter', - $input: $( '' ) - .byteLimit( 6, function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - - // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); - } ), - sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length - expected: 'User:Sample' - }); - - byteLimitTest({ - description: 'Limit using the maxlength attribute and pass a callback as input filter', - $input: $( '' ) - .attr( 'maxlength', '6' ) - .byteLimit( function ( val ) { - // Invalid title - if ( val === '' ) { - return ''; - } - - // Return without namespace prefix - return new mw.Title( String( val ) ).getMain(); - } ), - sample: 'User:Sample', - hasLimit: true, - limit: 6, // 'Sample' length - expected: 'User:Sample' - }); - - QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) { - var $el, $elA, $elB; - - $el = $( '' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit(); - - assert.strictEqual( $el.attr( 'maxlength' ), '7', 'maxlength attribute unchanged for simple limit' ); - - $el = $( '' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 12 ); - - assert.strictEqual( $el.attr( 'maxlength' ), '12', 'maxlength attribute updated for custom limit' ); - - $el = $( '' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ) - .byteLimit( 12, function ( val ) { - return val; - } ); - - assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' ); - - $elA = $( '' ) - .addClass( 'mw-test-byteLimit-foo' ) - .attr( 'maxlength', '7' ) - .appendTo( '#qunit-fixture' ); - - $elB = $( '' ) - .addClass( 'mw-test-byteLimit-foo' ) - .attr( 'maxlength', '12' ) - .appendTo( '#qunit-fixture' ); - - $el = $( '.mw-test-byteLimit-foo' ); - - assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' ); - - $el.byteLimit(); - }); - -}( jQuery, mediaWiki ) ); diff --git a/tests/qunit/suites/resources/jquery/jquery.client.test.js b/tests/qunit/suites/resources/jquery/jquery.client.test.js deleted file mode 100644 index bf62b39a..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.client.test.js +++ /dev/null @@ -1,317 +0,0 @@ -QUnit.module( 'jquery.client', QUnit.newMwEnvironment() ); - -/** Number of user-agent defined */ -var uacount = 0; - -var uas = (function () { - - // Object keyed by userAgent. Value is an array (human-readable name, client-profile object, navigator.platform value) - // Info based on results from http://toolserver.org/~krinkle/testswarm/job/174/ - var uas = { - // Internet Explorer 6 - // Internet Explorer 7 - 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)': { - title: 'Internet Explorer 7', - platform: 'Win32', - profile: { - "name": "msie", - "layout": "trident", - "layoutVersion": "unknown", - "platform": "win", - "version": "7.0", - "versionBase": "7", - "versionNumber": 7 - }, - wikiEditor: { - ltr: true, - rtl: false - } - }, - // Internet Explorer 8 - // Internet Explorer 9 - // Internet Explorer 10 - 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)': { - title: 'Internet Explorer 10', - platform: 'Win32', - profile: { - "name": "msie", - "layout": "trident", - "layoutVersion": "unknown", // should be able to report 6? - "platform": "win", - "version": "10.0", - "versionBase": "10", - "versionNumber": 10 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 2 - // Firefox 3.5 - 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.19) Gecko/20110420 Firefox/3.5.19': { - title: 'Firefox 3.5', - platform: 'MacIntel', - profile: { - "name": "firefox", - "layout": "gecko", - "layoutVersion": 20110420, - "platform": "mac", - "version": "3.5.19", - "versionBase": "3", - "versionNumber": 3.5 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 3.6 - 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110422 Ubuntu/10.10 (maverick) Firefox/3.6.17': { - title: 'Firefox 3.6', - platform: 'Linux i686', - profile: { - "name": "firefox", - "layout": "gecko", - "layoutVersion": 20110422, - "platform": "linux", - "version": "3.6.17", - "versionBase": "3", - "versionNumber": 3.6 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 4 - 'Mozilla/5.0 (Windows NT 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1': { - title: 'Firefox 4', - platform: 'Win32', - profile: { - "name": "firefox", - "layout": "gecko", - "layoutVersion": 20100101, - "platform": "win", - "version": "4.0.1", - "versionBase": "4", - "versionNumber": 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 10 nightly build - 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0a1) Gecko/20111103 Firefox/10.0a1': { - title: 'Firefox 10 nightly', - platform: 'Linux', - profile: { - "name": "firefox", - "layout": "gecko", - "layoutVersion": 20111103, - "platform": "linux", - "version": "10.0a1", - "versionBase": "10", - "versionNumber": 10 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Firefox 5 - // Safari 3 - // Safari 4 - 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; nl-nl) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7': { - title: 'Safari 4', - platform: 'MacIntel', - profile: { - "name": "safari", - "layout": "webkit", - "layoutVersion": 531, - "platform": "mac", - "version": "4.0.5", - "versionBase": "4", - "versionNumber": 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - 'Mozilla/5.0 (Windows; U; Windows NT 6.0; cs-CZ) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7': { - title: 'Safari 4', - platform: 'Win32', - profile: { - "name": "safari", - "layout": "webkit", - "layoutVersion": 533, - "platform": "win", - "version": "4.0.5", - "versionBase": "4", - "versionNumber": 4 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Safari 5 - // Opera 10 - // Chrome 5 - // Chrome 6 - // Chrome 7 - // Chrome 8 - // Chrome 9 - // Chrome 10 - // Chrome 11 - // Chrome 12 - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.112 Safari/534.30': { - title: 'Chrome 12', - platform: 'MacIntel', - profile: { - "name": "chrome", - "layout": "webkit", - "layoutVersion": 534, - "platform": "mac", - "version": "12.0.742.112", - "versionBase": "12", - "versionNumber": 12 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.68 Safari/534.30': { - title: 'Chrome 12', - platform: 'Linux i686', - profile: { - "name": "chrome", - "layout": "webkit", - "layoutVersion": 534, - "platform": "linux", - "version": "12.0.742.68", - "versionBase": "12", - "versionNumber": 12 - }, - wikiEditor: { - ltr: true, - rtl: true - } - }, - // Bug #34924 - 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.34 (KHTML, like Gecko) rekonq Safari/534.34': { - title: 'Rekonq', - platform: 'Linux i686', - profile: { - "name": "rekonq", - "layout": "webkit", - "layoutVersion": 534, - "platform": "linux", - "version": "534.34", - "versionBase": "534", - "versionNumber": 534.34 - }, - wikiEditor: { - ltr: true, - rtl: true - } - } - }; - $.each( uas, function () { - uacount++; - }); - return uas; -}()); - -QUnit.test( 'profile userAgent support', uacount, function ( assert ) { - // Generate a client profile object and compare recursively - var uaTest = function( rawUserAgent, data ) { - var ret = $.client.profile( { - userAgent: rawUserAgent, - platform: data.platform - } ); - assert.deepEqual( ret, data.profile, 'Client profile support check for ' + data.title + ' (' + data.platform + '): ' + rawUserAgent ); - }; - - // Loop through and run tests - $.each( uas, uaTest ); -} ); - -QUnit.test( 'profile return validation for current user agent', 7, function ( assert ) { - var p = $.client.profile(); - function unknownOrType( val, type, summary ) { - assert.ok( typeof val === type || val === 'unknown', summary ); - } - - assert.equal( typeof p, 'object', 'profile returns an object' ); - unknownOrType( p.layout, 'string', 'p.layout is a string (or "unknown")' ); - unknownOrType( p.layoutVersion, 'number', 'p.layoutVersion is a number (or "unknown")' ); - unknownOrType( p.platform, 'string', 'p.platform is a string (or "unknown")' ); - unknownOrType( p.version, 'string', 'p.version is a string (or "unknown")' ); - unknownOrType( p.versionBase, 'string', 'p.versionBase is a string (or "unknown")' ); - assert.equal( typeof p.versionNumber, 'number', 'p.versionNumber is a number' ); -}); - -// Example from WikiEditor -// Make sure to use raw numbers, a string like "7.0" would fail on a -// version 10 browser since in string comparaison "10" is before "7.0" :) -var testMap = { - 'ltr': { - 'msie': [['>=', 7.0]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - }, - 'rtl': { - 'msie': [['>=', 8]], - 'firefox': [['>=', 2]], - 'opera': [['>=', 9.6]], - 'safari': [['>=', 3]], - 'chrome': [['>=', 3]], - 'netscape': [['>=', 9]], - 'blackberry': false, - 'ipod': false, - 'iphone': false - } -}; - -QUnit.test( 'test', 1, function ( assert ) { - // .test() uses eval, make sure no exceptions are thrown - // then do a basic return value type check - var testMatch = $.client.test( testMap ); - - assert.equal( typeof testMatch, 'boolean', 'test returns a boolean value' ); - -}); - -QUnit.test( 'User-agent matches against WikiEditor\'s compatibility map', uacount * 2, function ( assert ) { - var $body = $( 'body' ), - bodyClasses = $body.attr( 'class' ); - - // Loop through and run tests - $.each( uas, function ( agent, data ) { - $.each( ['ltr', 'rtl'], function ( i, dir ) { - $body.removeClass( 'ltr rtl' ).addClass( dir ); - var profile = $.client.profile( { - userAgent: agent, - platform: data.platform - } ); - var testMatch = $.client.test( testMap, profile ); - $body.removeClass( dir ); - - assert.equal( testMatch, data.wikiEditor[dir], 'testing comparison based on ' + dir + ', ' + agent ); - }); - }); - - // Restore body classes - $body.attr( 'class', bodyClasses ); -}); - diff --git a/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js b/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js deleted file mode 100644 index 7b37f5a0..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js +++ /dev/null @@ -1,58 +0,0 @@ -QUnit.module( 'jquery.colorUtil', QUnit.newMwEnvironment() ); - -QUnit.test( 'getRGB', 18, function ( assert ) { - assert.strictEqual( $.colorUtil.getRGB(), undefined, 'No arguments' ); - assert.strictEqual( $.colorUtil.getRGB( '' ), undefined, 'Empty string' ); - assert.deepEqual( $.colorUtil.getRGB( [0, 100, 255] ), [0, 100, 255], 'Parse array of rgb values' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0,100,255)' ), [0, 100, 255], 'Parse simple rgb string' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0, 100, 255)' ), [0, 100, 255], 'Parse simple rgb string with spaces' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%,20%,40%)' ), [0, 51, 102], 'Parse rgb string with percentages' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgb(0%, 20%, 40%)' ), [0, 51, 102], 'Parse rgb string with percentages and spaces' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2ddee' ), [242, 221, 238], 'Hex string: 6 char lowercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2DDEE' ), [242, 221, 238], 'Hex string: 6 char uppercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#f2DdEe' ), [242, 221, 238], 'Hex string: 6 char mixed' ); - assert.deepEqual( $.colorUtil.getRGB( '#eee' ), [238, 238, 238], 'Hex string: 3 char lowercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#EEE' ), [238, 238, 238], 'Hex string: 3 char uppercase' ); - assert.deepEqual( $.colorUtil.getRGB( '#eEe' ), [238, 238, 238], 'Hex string: 3 char mixed' ); - assert.deepEqual( $.colorUtil.getRGB( 'rgba(0, 0, 0, 0)' ), [255, 255, 255], 'Zero rgba for Safari 3; Transparent (whitespace)' ); - - // Perhaps this is a bug in colorUtil, but it is the current behaviour so, let's keep - // track of it, so we will know in case it would ever change. - assert.strictEqual( $.colorUtil.getRGB( 'rgba(0,0,0,0)' ), undefined, 'Zero rgba without whitespace' ); - - assert.deepEqual( $.colorUtil.getRGB( 'lightGreen' ), [144, 238, 144], 'Color names (lightGreen)' ); - assert.deepEqual( $.colorUtil.getRGB( 'transparent' ), [255, 255, 255], 'Color names (transparent)' ); - assert.strictEqual( $.colorUtil.getRGB( 'mediaWiki' ), undefined, 'Inexisting color name' ); -}); - -QUnit.test( 'rgbToHsl', 1, function ( assert ) { - var hsl = $.colorUtil.rgbToHsl( 144, 238, 144 ); - - // Cross-browser differences in decimals... - // Round to two decimals so they can be more reliably checked. - var dualDecimals = function(a,b){ - return Math.round(a*100)/100; - }; - // Re-create the rgbToHsl return array items, limited to two decimals. - var ret = [dualDecimals(hsl[0]), dualDecimals(hsl[1]), dualDecimals(hsl[2])]; - - assert.deepEqual( ret, [0.33, 0.73, 0.75], 'rgb(144, 238, 144): hsl(0.33, 0.73, 0.75)' ); -}); - -QUnit.test( 'hslToRgb', 1, function ( assert ) { - var rgb = $.colorUtil.hslToRgb( 0.3, 0.7, 0.8 ); - - // Cross-browser differences in decimals... - // Re-create the hslToRgb return array items, rounded to whole numbers. - var ret = [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2])]; - - assert.deepEqual( ret ,[183, 240, 168], 'hsl(0.3, 0.7, 0.8): rgb(183, 240, 168)' ); -}); - -QUnit.test( 'getColorBrightness', 2, function ( assert ) { - var a = $.colorUtil.getColorBrightness( 'red', +0.1 ); - assert.equal( a, 'rgb(255,50,50)', 'Start with named color "red", brighten 10%' ); - - var b = $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 ); - assert.equal( b, 'rgb(118,29,29)', 'Start with rgb string "rgb(200,50,50)", darken 20%' ); -}); diff --git a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js b/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js deleted file mode 100644 index a3079835..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js +++ /dev/null @@ -1,35 +0,0 @@ -QUnit.asyncTest('jquery.delayedBind with data option', 2, function ( assert ) { - var $fixture = $('
    ').appendTo('#qunit-fixture'), - data = { magic: "beeswax" }, - delay = 50; - - $fixture.delayedBind(delay, 'testevent', data, function ( e ) { - QUnit.start(); // continue! - assert.ok( true, 'testevent fired'); - assert.ok( e.data === data, 'data is passed through delayedBind'); - }); - - // We'll trigger it thrice, but it should only happen once. - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); -}); - -QUnit.asyncTest('jquery.delayedBind without data option', 1, function ( assert ) { - var $fixture = $('
    ').appendTo('#qunit-fixture'), - data = { magic: "beeswax" }, - delay = 50; - - $fixture.delayedBind(delay, 'testevent', function ( e ) { - QUnit.start(); // continue! - assert.ok(true, 'testevent fired'); - }); - - // We'll trigger it thrice, but it should only happen once. - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); - $fixture.trigger( 'testevent', {} ); -}); - diff --git a/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js b/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js deleted file mode 100644 index 6eef1abb..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js +++ /dev/null @@ -1,11 +0,0 @@ -QUnit.module( 'jquery.getAttrs', QUnit.newMwEnvironment() ); - -QUnit.test( 'Check', 1, function ( assert ) { - var attrs = { - foo: 'bar', - 'class': 'lorem' - }, - $el = jQuery( '
    ', attrs ); - - assert.deepEqual( $el.getAttrs(), attrs, 'getAttrs() return object should match the attributes set, no more, no less' ); -} ); diff --git a/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js b/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js deleted file mode 100644 index a94dca31..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.highlightText.test.js +++ /dev/null @@ -1,232 +0,0 @@ -QUnit.module( 'jquery.highlightText', QUnit.newMwEnvironment() ); - -QUnit.test( 'Check', function ( assert ) { - var $fixture, cases = [ - { - desc: 'Test 001', - text: 'Blue Öyster Cult', - highlight: 'Blue', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 002', - text: 'Blue Öyster Cult', - highlight: 'Blue ', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 003', - text: 'Blue Öyster Cult', - highlight: 'Blue Ö', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 004', - text: 'Blue Öyster Cult', - highlight: 'Blue Öy', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 005', - text: 'Blue Öyster Cult', - highlight: ' Blue', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 006', - text: 'Blue Öyster Cult', - highlight: ' Blue ', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 007', - text: 'Blue Öyster Cult', - highlight: ' Blue Ö', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 008', - text: 'Blue Öyster Cult', - highlight: ' Blue Öy', - expected: 'Blue Öyster Cult' - }, - { - desc: 'Test 009: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Österreich', - expected: 'Österreich' - }, - { - desc: 'Test 010: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Ö', - expected: 'Österreich' - }, - { - desc: 'Test 011: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Öst', - expected: 'Österreich' - }, - { - desc: 'Test 012: Highlighter broken on starting Umlaut?', - text: 'Österreich', - highlight: 'Oe', - expected: 'Österreich' - }, - { - desc: 'Test 013: Highlighter broken on punctuation mark?', - text: 'So good. To be there', - highlight: 'good', - expected: 'So good. To be there' - }, - { - desc: 'Test 014: Highlighter broken on space?', - text: 'So good. To be there', - highlight: 'be', - expected: 'So good. To be there' - }, - { - desc: 'Test 015: Highlighter broken on space?', - text: 'So good. To be there', - highlight: ' be', - expected: 'So good. To be there' - }, - { - desc: 'Test 016: Highlighter broken on space?', - text: 'So good. To be there', - highlight: 'be ', - expected: 'So good. To be there' - }, - { - desc: 'Test 017: Highlighter broken on space?', - text: 'So good. To be there', - highlight: ' be ', - expected: 'So good. To be there' - }, - { - desc: 'Test 018: en de Highlighter broken on special character at the end?', - text: 'So good. xbß', - highlight: 'xbß', - expected: 'So good. xbß' - }, - { - desc: 'Test 019: en de Highlighter broken on special character at the end?', - text: 'So good. xbß.', - highlight: 'xbß.', - expected: 'So good. xbß.' - }, - { - desc: 'Test 020: RTL he Hebrew', - text: 'חסיד אומות העולם', - highlight: 'חסיד אומות העולם', - expected: 'חסיד אומות העולם' - }, - { - desc: 'Test 021: RTL he Hebrew', - text: 'חסיד אומות העולם', - highlight: 'חסי', - expected: 'חסיד אומות העולם' - }, - { - desc: 'Test 022: ja Japanese', - text: '諸国民の中の正義の人', - highlight: '諸国民の中の正義の人', - expected: '諸国民の中の正義の人' - }, - { - desc: 'Test 023: ja Japanese', - text: '諸国民の中の正義の人', - highlight: '諸国', - expected: '諸国民の中の正義の人' - }, - { - desc: 'Test 024: fr French text and « french quotes » (guillemets)', - text: "« L'oiseau est sur l’île »", - highlight: "« L'oiseau est sur l’île »", - expected: '« L\'oiseau est sur l’île »' - }, - { - desc: 'Test 025: fr French text and « french quotes » (guillemets)', - text: "« L'oiseau est sur l’île »", - highlight: "« L'oise", - expected: '« L\'oiseau est sur l’île »' - }, - { - desc: 'Test 025a: fr French text and « french quotes » (guillemets) - does it match the single strings "«" and "L" separately?', - text: "« L'oiseau est sur l’île »", - highlight: "« L", - expected: '« L\'oiseau est sur l’île »' - }, - { - desc: 'Test 026: ru Russian', - text: 'Праведники мира', - highlight: 'Праведники мира', - expected: 'Праведники мира' - }, - { - desc: 'Test 027: ru Russian', - text: 'Праведники мира', - highlight: 'Праве', - expected: 'Праведники мира' - }, - { - desc: 'Test 028 ka Georgian', - text: 'მთავარი გვერდი', - highlight: 'მთავარი გვერდი', - expected: 'მთავარი გვერდი' - }, - { - desc: 'Test 029 ka Georgian', - text: 'მთავარი გვერდი', - highlight: 'მთა', - expected: 'მთავარი გვერდი' - }, - { - desc: 'Test 030 hy Armenian', - text: 'Նոնա Գափրինդաշվիլի', - highlight: 'Նոնա Գափրինդաշվիլի', - expected: 'Նոնա Գափրինդաշվիլի' - }, - { - desc: 'Test 031 hy Armenian', - text: 'Նոնա Գափրինդաշվիլի', - highlight: 'Նոն', - expected: 'Նոնա Գափրինդաշվիլի' - }, - { - desc: 'Test 032: th Thai', - text: 'พอล แอร์ดิช', - highlight: 'พอล แอร์ดิช', - expected: 'พอล แอร์ดิช' - }, - { - desc: 'Test 033: th Thai', - text: 'พอล แอร์ดิช', - highlight: 'พอ', - expected: 'พอล แอร์ดิช' - }, - { - desc: 'Test 034: RTL ar Arabic', - text: 'بول إيردوس', - highlight: 'بول إيردوس', - expected: 'بول إيردوس' - }, - { - desc: 'Test 035: RTL ar Arabic', - text: 'بول إيردوس', - highlight: 'بو', - expected: 'بول إيردوس' - } - ]; - QUnit.expect( cases.length ); - - $.each( cases, function ( i, item ) { - $fixture = $( '

    ' ).text( item.text ).highlightText( item.highlight ); - assert.equal( - $fixture.html(), - $( '

    ' ).html( item.expected ).html(), // re-parse to normalize! - item.desc || undefined - ); - } ); -} ); diff --git a/tests/qunit/suites/resources/jquery/jquery.localize.test.js b/tests/qunit/suites/resources/jquery/jquery.localize.test.js deleted file mode 100644 index c8e1d9f9..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.localize.test.js +++ /dev/null @@ -1,133 +0,0 @@ -QUnit.module( 'jquery.localize', QUnit.newMwEnvironment() ); - -QUnit.test( 'Handle basic replacements', 4, function ( assert ) { - var html, $lc; - mw.messages.set( 'basic', 'Basic stuff' ); - - // Tag: html:msg - html = '

    '; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.text(), 'Basic stuff', 'Tag: html:msg' ); - - // Attribute: title-msg - html = '
    '; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Basic stuff', 'Attribute: title-msg' ); - - // Attribute: alt-msg - html = '
    '; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'alt' ), 'Basic stuff', 'Attribute: alt-msg' ); - - // Attribute: placeholder-msg - html = '
    '; - $lc = $( html ).localize().find( 'input' ); - - assert.strictEqual( $lc.attr( 'placeholder' ), 'Basic stuff', 'Attribute: placeholder-msg' ); -} ); - -QUnit.test( 'Proper escaping', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'properfoo', '' ); - - // This is handled by jQuery inside $.fn.localize, just a simple sanity checked - // making sure it is actually using text() and attr() (or something with the same effect) - - // Text escaping - html = '
    '; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.text(), mw.msg( 'properfoo' ), 'Content is inserted as text, not as html.' ); - - // Attribute escaping - html = '
    '; - $lc = $( html ).localize().find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), mw.msg( 'properfoo' ), 'Attributes are not inserted raw.' ); -} ); - -QUnit.test( 'Options', 7, function ( assert ) { - mw.messages.set( { - 'foo-lorem': 'Lorem', - 'foo-ipsum': 'Ipsum', - 'foo-bar-title': 'Read more about bars', - 'foo-bar-label': 'The Bars', - 'foo-bazz-title': 'Read more about bazz at $1 (last modified: $2)', - 'foo-bazz-label': 'The Bazz ($1)', - 'foo-welcome': 'Welcome to $1! (last visit: $2)' - } ); - var html, $lc, attrs, x, sitename = 'Wikipedia'; - - // Message key prefix - html = '
    '; - $lc = $( html ).localize( { - prefix: 'foo-' - } ).find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Lorem', 'Message key prefix - attr' ); - assert.strictEqual( $lc.text(), 'Ipsum', 'Message key prefix - text' ); - - // Variable keys mapping - x = 'bar'; - html = '
    '; - $lc = $( html ).localize( { - keys: { - 'title': 'foo-' + x + '-title', - 'label': 'foo-' + x + '-label' - } - } ).find( 'span' ); - - assert.strictEqual( $lc.attr( 'title' ), 'Read more about bars', 'Variable keys mapping - attr' ); - assert.strictEqual( $lc.text(), 'The Bars', 'Variable keys mapping - text' ); - - // Passing parameteters to mw.msg - html = '
    '; - $lc = $( html ).localize( { - params: { - 'foo-welcome': [sitename, 'yesterday'] - } - } ).find( 'span' ); - - assert.strictEqual( $lc.text(), 'Welcome to Wikipedia! (last visit: yesterday)', 'Passing parameteters to mw.msg' ); - - // Combination of options prefix, params and keys - x = 'bazz'; - html = '
    '; - $lc = $( html ).localize( { - prefix: 'foo-', - keys: { - 'title': x + '-title', - 'label': x + '-label' - }, - params: { - 'title': [sitename, '3 minutes ago'], - 'label': [sitename, '3 minutes ago'] - - } - } ).find( 'span' ); - - assert.strictEqual( $lc.text(), 'The Bazz (Wikipedia)', 'Combination of options prefix, params and keys - text' ); - assert.strictEqual( $lc.attr( 'title' ), 'Read more about bazz at Wikipedia (last modified: 3 minutes ago)', 'Combination of options prefix, params and keys - attr' ); -} ); - -QUnit.test( 'Handle data text', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'option-one', 'Item 1' ); - mw.messages.set( 'option-two', 'Item 2' ); - html = ''; - $lc = $( html ).localize().find( 'option' ); - assert.strictEqual( $lc.eq( 0 ).text(), mw.msg( 'option-one' ), 'data-msg-text becomes text of options' ); - assert.strictEqual( $lc.eq( 1 ).text(), mw.msg( 'option-two' ), 'data-msg-text becomes text of options' ); -} ); - -QUnit.test( 'Handle data html', 2, function ( assert ) { - var html, $lc; - mw.messages.set( 'html', 'behold... there is a link here!!' ); - html = '
    '; - $lc = $( html ).localize().find( 'a' ); - assert.strictEqual( $lc.length, 1, 'link is created' ); - assert.strictEqual( $lc.text(), 'link', 'the link text got added' ); -} ); diff --git a/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js b/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js deleted file mode 100644 index 5b566ae0..00000000 --- a/tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js +++ /dev/null @@ -1,58 +0,0 @@ -QUnit.module( 'jquery.mwExtension', QUnit.newMwEnvironment() ); - -QUnit.test( 'String functions', function ( assert ) { - - assert.equal( $.trimLeft( ' foo bar ' ), 'foo bar ', 'trimLeft' ); - assert.equal( $.trimRight( ' foo bar ' ), ' foo bar', 'trimRight' ); - assert.equal( $.ucFirst( 'foo' ), 'Foo', 'ucFirst' ); - - assert.equal( $.escapeRE( '