diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2013-12-08 09:55:49 +0100 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2013-12-08 09:55:49 +0100 |
commit | 4ac9fa081a7c045f6a9f1cfc529d82423f485b2e (patch) | |
tree | af68743f2f4a47d13f2b0eb05f5c4aaf86d8ea37 /tests | |
parent | af4da56f1ad4d3ef7b06557bae365da2ea27a897 (diff) |
Update to MediaWiki 1.22.0
Diffstat (limited to 'tests')
339 files changed, 15236 insertions, 12138 deletions
diff --git a/tests/RunSeleniumTests.php b/tests/RunSeleniumTests.php deleted file mode 100644 index b7320cb1..00000000 --- a/tests/RunSeleniumTests.php +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env php -<?php -/** - * @file - * @ingroup Maintenance - * @copyright Copyright © Wikimedia Deuschland, 2009 - * @author Hallo Welt! Medienwerkstatt GmbH - * @author Markus Glaser, Dan Nessett, Priyanka Dhanda - * initial idea by Daniel Kinzler - * - * 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 - */ - -if ( PHP_SAPI != 'cli' ) { - die( "Run me from the command line please.\n" ); -} - -define( 'SELENIUMTEST', true ); - -require( __DIR__ . '/../maintenance/Maintenance.php' ); - -require_once( 'PHPUnit/Runner/Version.php' ); -if ( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) { - # 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 behavior 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 index c1c301f6..00ce13c8 100644 --- a/tests/TestsAutoLoader.php +++ b/tests/TestsAutoLoader.php @@ -30,14 +30,16 @@ $wgAutoloadClasses += array( 'DbTestPreviewer' => "$testDir/testHelpers.inc", 'DbTestRecorder' => "$testDir/testHelpers.inc", 'DelayedParserTest' => "$testDir/testHelpers.inc", + 'ParserTestResult' => "$testDir/parser/ParserTestResult.php", 'TestFileIterator' => "$testDir/testHelpers.inc", 'TestRecorder' => "$testDir/testHelpers.inc", + 'ITestRecorder' => "$testDir/testHelpers.inc", # tests/phpunit 'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php", 'MediaWikiPHPUnitCommand' => "$testDir/phpunit/MediaWikiPHPUnitCommand.php", + 'MediaWikiPHPUnitTestListener' => "$testDir/phpunit/MediaWikiPHPUnitTestListener.php", 'MediaWikiLangTestCase' => "$testDir/phpunit/MediaWikiLangTestCase.php", - 'MediaWikiProvide' => "$testDir/phpunit/includes/Providers.php", 'TestUser' => "$testDir/phpunit/includes/TestUser.php", # tests/phpunit/includes @@ -48,9 +50,7 @@ $wgAutoloadClasses += array( //db 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php", 'PageORMTableForTesting' => "$testDir/phpunit/includes/db/ORMTableTest.php", - - //Selenium - 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php", + 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php", # tests/phpunit/includes/api 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php", @@ -73,14 +73,25 @@ $wgAutoloadClasses += array( # tests/phpunit/includes/parser 'NewParserTest' => "$testDir/phpunit/includes/parser/NewParserTest.php", + 'MediaWikiParserTest' => "$testDir/phpunit/includes/parser/MediaWikiParserTest.php", # tests/phpunit/includes/libs 'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php", + # tests/phpunit/media + 'FakeDimensionFile' => "$testDir/phpunit/includes/media/FakeDimensionFile.php", + # tests/phpunit/includes/site 'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php", 'TestSites' => "$testDir/phpunit/includes/site/TestSites.php", + # tests/phpunit/mocks + 'MockFSFile' => "$testDir/phpunit/mocks/filebackend/MockFSFile.php", + 'MockFileBackend' => "$testDir/phpunit/mocks/filebackend/MockFileBackend.php", + 'MockBitmapHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + 'MockImageHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + 'MockSvgHandler' => "$testDir/phpunit/mocks/media/MockBitmapHandler.php", + # tests/phpunit/languages 'LanguageClassesTestCase' => "$testDir/phpunit/languages/LanguageClassesTestCase.php", @@ -90,15 +101,4 @@ $wgAutoloadClasses += array( # tests/parser 'ParserTest' => "$testDir/parser/parserTest.inc", 'ParserTestParserHook' => "$testDir/parser/parserTestsParserHook.php", - - # tests/selenium - 'Selenium' => "$testDir/selenium/Selenium.php", - 'SeleniumLoader' => "$testDir/selenium/SeleniumLoader.php", - 'SeleniumTestCase' => "$testDir/selenium/SeleniumTestCase.php", - 'SeleniumTestConsoleLogger' => "$testDir/selenium/SeleniumTestConsoleLogger.php", - 'SeleniumTestConstants' => "$testDir/selenium/SeleniumTestConstants.php", - 'SeleniumTestHTMLLogger' => "$testDir/selenium/SeleniumTestHTMLLogger.php", - 'SeleniumTestListener' => "$testDir/selenium/SeleniumTestListener.php", - 'SeleniumTestSuite' => "$testDir/selenium/SeleniumTestSuite.php", - 'SeleniumConfig' => "$testDir/selenium/SeleniumConfig.php", ); diff --git a/tests/parser/ParserTestResult.php b/tests/parser/ParserTestResult.php new file mode 100644 index 00000000..d9ad773d --- /dev/null +++ b/tests/parser/ParserTestResult.php @@ -0,0 +1,42 @@ +<?php +/** + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @license GNU GPL v2 + * + * @file + */ + +/** + * Represent the result of a parser test. + * + * @since 1.22 + */ +class ParserTestResult { + /** + * Description of the parser test. + * + * This is usually the text used to describe a parser test in the .txt + * files. It is initialized on a construction and you most probably + * never want to change it. + */ + public $description; + /** Text that was expected */ + public $expected; + /** Actual text rendered */ + public $actual; + + /** + * @param $description string A short text describing the parser test + * usually the text in the parser test .txt file. The description + * is later available using the property $description. + */ + public function __construct( $description ) { + $this->description = $description; + } + + /** Whether the test passed */ + public function isSuccess() { + return $this->expected === $this->actual; + } +} diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc index ce621f4e..58ea1ed0 100644 --- a/tests/parser/parserTest.inc +++ b/tests/parser/parserTest.inc @@ -1,6 +1,8 @@ <?php /** - * Helper code for the MediaWiki parser test suite. + * Helper code for the MediaWiki parser test suite. Some code is duplicated + * in PHPUnit's NewParserTests.php, so you'll probably want to update both + * at the same time. * * Copyright © 2004, 2010 Brion Vibber <brion@pobox.com> * http://www.mediawiki.org/ @@ -31,22 +33,22 @@ */ class ParserTest { /** - * boolean $color whereas output should be colorized + * @var bool $color whereas output should be colorized */ private $color; /** - * boolean $showOutput Show test output + * @var bool $showOutput Show test output */ private $showOutput; /** - * boolean $useTemporaryTables Use temporary tables for the temporary database + * @var bool $useTemporaryTables Use temporary tables for the temporary database */ private $useTemporaryTables = true; /** - * boolean $databaseSetupDone True if the database has been set up + * @var bool $databaseSetupDone True if the database has been set up */ private $databaseSetupDone = false; @@ -63,7 +65,7 @@ class ParserTest { private $dbClone; /** - * string $oldTablePrefix Original table prefix + * @var string $oldTablePrefix Original table prefix */ private $oldTablePrefix; @@ -141,15 +143,14 @@ class ParserTest { static function setUp() { global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, - $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, + $wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, - $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, + $wgArticlePath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers; $wgScript = '/index.php'; $wgScriptPath = '/'; $wgArticlePath = '/wiki/$1'; - $wgStyleSheetPath = '/skins'; $wgStylePath = '/skins'; $wgExtensionAssetsPath = '/extensions'; $wgThumbnailScriptPath = false; @@ -181,6 +182,9 @@ class ParserTest { $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; $wgNamespaceAliases['Image'] = NS_FILE; $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + # add a namespace shadowing a interwiki link, to test + # proper precedence when resolving links. (bug 51680) + $wgExtraNamespaces[100] = 'MemoryAlpha'; // XXX: tests won't run without this (for CACHE_DB) if ( $wgMainCacheType === CACHE_DB ) { @@ -211,6 +215,73 @@ class ParserTest { $wgStyleDirectory = "$IP/skins"; } + self::setupInterwikis(); + } + + /** + * Insert hardcoded interwiki in the lookup table. + * + * This function insert a set of well known interwikis that are used in + * the parser tests. They can be considered has fixtures are injected in + * the interwiki cache by using the 'InterwikiLoadPrefix' hook. + * Since we are not interested in looking up interwikis in the database, + * the hook completely replace the existing mechanism (hook returns false). + */ + public static function setupInterwikis() { + # Hack: insert a few Wikipedia in-project interwiki prefixes, + # for testing inter-language links + Hooks::register( 'InterwikiLoadPrefix', function ( $prefix, &$iwData ) { + static $testInterwikis = array( + 'wikipedia' => array( + 'iw_url' => 'http://en.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'meatball' => array( + 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'memoryalpha' => array( + 'iw_url' => 'http://www.memory-alpha.org/en/index.php/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 0 ), + 'zh' => array( + 'iw_url' => 'http://zh.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'es' => array( + 'iw_url' => 'http://es.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'fr' => array( + 'iw_url' => 'http://fr.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + 'ru' => array( + 'iw_url' => 'http://ru.wikipedia.org/wiki/$1', + 'iw_api' => '', + 'iw_wikiid' => '', + 'iw_local' => 1 ), + ); + if ( array_key_exists( $prefix, $testInterwikis ) ) { + $iwData = $testInterwikis[$prefix]; + } + + // We only want to rely on the above fixtures + return false; + } );// hooks::register + } + + /** + * Remove the hardcoded interwiki lookup table. + */ + public static function tearDownInterwikis() { + Hooks::clear( 'InterwikiLoadPrefix' ); } public function setupRecorder( $options ) { @@ -378,7 +449,12 @@ class ParserTest { */ public function runTestsFromFiles( $filenames ) { $ok = false; + + // be sure, ParserTest::addArticle has correct language set, + // so that system messages gets into the right language cache + $GLOBALS['wgLanguageCode'] = 'en'; $GLOBALS['wgContLang'] = Language::factory( 'en' ); + $this->recorder->start(); try { $this->setupDatabase(); @@ -418,6 +494,9 @@ class ParserTest { /** * Get a Parser object + * + * @param string $preprocessor + * @return Parser */ function getParser( $preprocessor = null ) { global $wgParserConf; @@ -487,9 +566,10 @@ class ParserTest { } elseif ( isset( $opts['comment'] ) ) { $out = Linker::formatComment( $input, $title, $local ); } elseif ( isset( $opts['preload'] ) ) { - $out = $parser->getpreloadText( $input, $title, $options ); + $out = $parser->getPreloadText( $input, $title, $options ); } else { $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); $out = $output->getText(); if ( isset( $opts['showtitle'] ) ) { @@ -518,18 +598,23 @@ class ParserTest { } $this->teardownGlobals(); - return $this->showTestResult( $desc, $result, $out ); + + $testResult = new ParserTestResult( $desc ); + $testResult->expected = $result; + $testResult->actual = $out; + + return $this->showTestResult( $testResult ); } /** - * + * Refactored in 1.22 to use ParserTestResult */ - function showTestResult( $desc, $result, $out ) { - if ( $result === $out ) { - $this->showSuccess( $desc ); + function showTestResult( ParserTestResult $testResult ) { + if ( $testResult->isSuccess() ) { + $this->showSuccess( $testResult ); return true; } else { - $this->showFailure( $desc, $result, $out ); + $this->showFailure( $testResult ); return false; } } @@ -537,7 +622,7 @@ class ParserTest { /** * 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 $opts array: Options array to look in * @param $default Mixed: default value returned if not found */ private static function getOptionValue( $key, $opts, $default ) { @@ -664,11 +749,10 @@ class ParserTest { ), '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'] ), + 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), 'wgLang' => null, 'wgContLang' => null, 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ), @@ -678,8 +762,10 @@ class ParserTest { 'wgNoFollowDomainExceptions' => array(), 'wgThumbnailScriptPath' => false, 'wgUseImageResize' => true, + 'wgSVGConverter' => 'null', + 'wgSVGConverters' => array( 'null' => 'echo "1">$output' ), 'wgLocaltimezone' => 'UTC', - 'wgAllowExternalImages' => true, + 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), 'wgUseTidy' => false, 'wgDefaultLanguageVariant' => $variant, 'wgVariantArticlePath' => false, @@ -822,43 +908,9 @@ class ParserTest { '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 ) ); + $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(); @@ -866,19 +918,52 @@ class ParserTest { # Clear the message cache MessageCache::singleton()->clear(); + // Remember to update newParserTests.php after changing the below + // (and it uses a slightly different syntax just for teh lulz) $this->uploadDir = $this->setupUploadDir(); $user = User::createNew( 'WikiSysop' ); $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) ); + # note that the size/width/height/bits/etc of the file + # are actually set by inspecting the file itself; the arguments + # to recordUpload2 have no effect. That said, we try to make things + # match up so it is less confusing to readers of the code & tests. $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array( - 'size' => 12345, + 'size' => 7881, 'width' => 1941, 'height' => 220, - 'bits' => 24, + 'bits' => 8, 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '1', 16, 36, 31 ), + 'fileExists' => true + ), $this->db->timestamp( '20010115123500' ), $user ); + + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Thumb.png' ) ); + # again, note that size/width/height below are ignored; see above. + $image->recordUpload2( '', 'Upload of some lame thumbnail', 'Some lame thumbnail', array( + 'size' => 22589, + 'width' => 135, + 'height' => 135, + 'bits' => 8, + 'media_type' => MEDIATYPE_BITMAP, + 'mime' => 'image/png', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '2', 16, 36, 31 ), 'fileExists' => true + ), $this->db->timestamp( '20130225203040' ), $user ); + + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.svg' ) ); + $image->recordUpload2( '', 'Upload of some lame SVG', 'Some lame SVG', array( + 'size' => 12345, + 'width' => 240, + 'height' => 180, + 'bits' => 24, + 'media_type' => MEDIATYPE_DRAWING, + 'mime' => 'image/svg+xml', + '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]] @@ -891,7 +976,7 @@ class ParserTest { 'media_type' => MEDIATYPE_BITMAP, 'mime' => 'image/jpeg', 'metadata' => serialize( array() ), - 'sha1' => wfBaseConvert( '', 16, 36, 31 ), + 'sha1' => wfBaseConvert( '3', 16, 36, 31 ), 'fileExists' => true ), $this->db->timestamp( '20010115123500' ), $user ); } @@ -922,8 +1007,11 @@ class ParserTest { $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( "DROP TABLE pt_$table DROP CONSTRAINTS" ); + } else { + $this->db->query( "DROP TABLE `parsertest_$table`" ); + } } if ( $this->db->getType() == 'oracle' ) { @@ -960,9 +1048,15 @@ class ParserTest { wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); + wfMkdirParents( $dir . '/e/ea', null, __METHOD__ ); + copy( "$IP/skins/monobook/wiki.png", "$dir/e/ea/Thumb.png" ); wfMkdirParents( $dir . '/0/09', null, __METHOD__ ); copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - + wfMkdirParents( $dir . '/f/ff', null, __METHOD__ ); + copy( "$IP/skins/monobook/headbg.jpg", "$dir/f/ff/Foobar.svg" ); + file_put_contents( "$dir/f/ff/Foobar.svg", + '<?xml version="1.0" encoding="utf-8"?>' . + '<svg xmlns="http://www.w3.org/2000/svg" />' ); return $dir; } @@ -1008,8 +1102,18 @@ class ParserTest { "$dir/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg", "$dir/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg", + "$dir/e/ea/Thumb.png", + "$dir/0/09/Bad.jpg", + "$dir/f/ff/Foobar.svg", + "$dir/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png", + "$dir/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png", + "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png", ) ); @@ -1023,7 +1127,13 @@ class ParserTest { "$dir/thumb/3/3a/Foobar.jpg", "$dir/thumb/3/3a", "$dir/thumb/3", - + "$dir/e/ea", + "$dir/e", + "$dir/f/ff/", + "$dir/f/", + "$dir/thumb/f/ff/Foobar.svg", + "$dir/thumb/f/ff/", + "$dir/thumb/f/", "$dir/0/09/", "$dir/0/", "$dir/thumb", @@ -1070,10 +1180,12 @@ class ParserTest { /** * Print a happy success message. * - * @param $desc String: the test name + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult * @return Boolean */ - protected function showSuccess( $desc ) { + protected function showSuccess( ParserTestResult $testResult ) { if ( $this->showProgress ) { print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n"; } @@ -1085,28 +1197,29 @@ class ParserTest { * 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 + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult * @return Boolean */ - protected function showFailure( $desc, $result, $html ) { + protected function showFailure( ParserTestResult $testResult ) { 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 ); + $this->showTesting( $testResult->description ); } print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n"; if ( $this->showOutput ) { - print "--- Expected ---\n$result\n--- Actual ---\n$html\n"; + print "--- Expected ---\n{$testResult->expected}\n"; + print "--- Actual ---\n{$testResult->actual}\n"; } if ( $this->showDiffs ) { - print $this->quickDiff( $result, $html ); - if ( !$this->wellFormed( $html ) ) { + print $this->quickDiff( $testResult->expected, $testResult->actual ); + if ( !$this->wellFormed( $testResult->actual ) ) { print "XML error: $this->mXmlError\n"; } } @@ -1125,7 +1238,9 @@ class ParserTest { * @param $outFileTail String: tailing for the output file name * @return String */ - protected function quickDiff( $input, $output, $inFileTail = 'expected', $outFileTail = 'actual' ) { + 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(); @@ -1141,9 +1256,10 @@ class ParserTest { global $wgDiff3; // we assume that people with diff3 also have usual diff - $diff = ( wfIsWindows() && !$wgDiff3 ) - ? `fc $shellInfile $shellOutfile` - : `diff -au $shellInfile $shellOutfile`; + $shellCommand = ( wfIsWindows() && !$wgDiff3 ) ? 'fc' : 'diff -au'; + + $diff = wfShellExec( "$shellCommand $shellInfile $shellOutfile" ); + unlink( $infile ); unlink( $outfile ); @@ -1343,7 +1459,7 @@ class ParserTest { } static function getFakeTimestamp( &$parser, &$ts ) { - $ts = 123; + $ts = 123; //parsed as '1970-01-01T00:02:03Z' return true; } } diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt index f0603e75..02a66b51 100644 --- a/tests/parser/parserTests.txt +++ b/tests/parser/parserTests.txt @@ -26,6 +26,11 @@ # 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 +# notoc disable table of contents +# +# You can also set the following parser properties via test options: +# wgEnableUploads, wgAllowExternalImages, wgMaxTocLevel, +# wgLinkHolderBatchSize, wgRawHtml # # For testing purposes, temporary articles can created: # !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle @@ -117,11 +122,30 @@ Template:table_attribs !! endarticle !! article +Template:table_cells +!! text +{{table_attribs}} || Bar || Baz +!! endarticle + +!! article +Template:image_attribs +!! text +<noinclude> +[[File:foobar.jpg|</noinclude>right|Caption text<noinclude>]]</noinclude> +!! endarticle + +!! article A?b !! text Weirdo titles! !! endarticle +!!article +Template:Bullet +!!text +* Bar +!!endarticle + ### ### Basic tests ### @@ -165,6 +189,206 @@ baz !! end !! test +Paragraphs with newline spacing with comment lines in between +!! input +---- +a +<!--foo--> +b +---- +a +<!--foo--><!--More than 1 comment, still stripped--> +b +---- +a + <!--foo--> <!----> <!-- bar --> +b +---- +a +<!--foo--> + +b +---- +a + +<!--foo--> +b +---- +a +<!--foo--> + + +b +---- +a + + +<!--foo--> +b +---- +!! result +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Paragraphs with newline spacing with non-empty white-space lines in between +!! input +---- +a + +b +---- +a + + +b +---- +!! result +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Paragraphs with newline spacing with non-empty mixed comment and white-space lines in between +!! input +---- +a + <!--foo--> +b +---- +a + <!--foo--><!--More than 1 comment doesn't disable stripping of this line!--> +b +---- +a + +<!--foo--> + <!--bar--> +b +---- +a + + <!--foo--> + <!--bar--> + +b +---- +!! result +<hr /> +<p>a +b +</p> +<hr /> +<p>a +b +</p> +<hr /> +<p>a +</p><p>b +</p> +<hr /> +<p>a +</p><p><br /> +b +</p> +<hr /> + +!! end + +!! test +Extra newlines: More paragraphs with indented comment +!! input +a + + <!--boo--> + +b +!!result +<p>a +</p><p><br /> +b +</p> +!!end + +!! test +Extra newlines followed by heading +!! input +a + + + +=b= +[[a]] + + +=b= +!! result +<p>a +</p><p><br /> +</p> +<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<p><a href="/index.php?title=A&action=edit&redlink=1" class="new" title="A (page does not exist)">a</a> +</p><p><br /> +</p> +<h1><span class="mw-headline" id="b_2">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> + +!! end + +!! test +Extra newlines between heading and content are swallowed +!! input +=b= + + + +[[a]] +!! result +<h1><span class="mw-headline" id="b">b</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: b">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<p><a href="/index.php?title=A&action=edit&redlink=1" class="new" title="A (page does not exist)">a</a> +</p> +!! end + +!! test Parsing an URL !! input http://fr.wikipedia.org/wiki/🍺 @@ -180,9 +404,12 @@ Simple list * Item 1 * Item 2 !! result -<ul><li> Item 1 -</li><li> Item 2 -</li></ul> +<ul> +<li> Item 1 +</li> +<li> Item 2 +</li> +</ul> !! end @@ -205,25 +432,72 @@ Italics and bold * plain l'''italic''plain * plain l''''bold''' plain !! result -<ul><li> plain -</li><li> plain<i>italic</i>plain -</li><li> plain<i>italic</i>plain<i>italic</i>plain -</li><li> plain<b>bold</b>plain -</li><li> plain<b>bold</b>plain<b>bold</b>plain -</li><li> plain<i>italic</i>plain<b>bold</b>plain -</li><li> plain<b>bold</b>plain<i>italic</i>plain -</li><li> plain<i>italic<b>bold-italic</b>italic</i>plain -</li><li> plain<b>bold<i>bold-italic</i>bold</b>plain -</li><li> plain<i><b>bold-italic</b>italic</i>plain -</li><li> plain<b><i>bold-italic</i>bold</b>plain -</li><li> plain<i>italic<b>bold-italic</b></i>plain -</li><li> plain<b>bold<i>bold-italic</i></b>plain -</li><li> plain l'<i>italic</i>plain -</li><li> plain l'<b>bold</b> plain -</li></ul> +<ul> +<li> plain +</li> +<li> plain<i>italic</i>plain +</li> +<li> plain<i>italic</i>plain<i>italic</i>plain +</li> +<li> plain<b>bold</b>plain +</li> +<li> plain<b>bold</b>plain<b>bold</b>plain +</li> +<li> plain<i>italic</i>plain<b>bold</b>plain +</li> +<li> plain<b>bold</b>plain<i>italic</i>plain +</li> +<li> plain<i>italic<b>bold-italic</b>italic</i>plain +</li> +<li> plain<b>bold<i>bold-italic</i>bold</b>plain +</li> +<li> plain<i><b>bold-italic</b>italic</i>plain +</li> +<li> plain<b><i>bold-italic</i>bold</b>plain +</li> +<li> plain<i>italic<b>bold-italic</b></i>plain +</li> +<li> plain<b>bold<i>bold-italic</i></b>plain +</li> +<li> plain l'<i>italic</i>plain +</li> +<li> plain l'<b>bold</b> plain +</li> +</ul> + +!! end + +# this example taken from the [[simple:Moon]] article (bug 47326) +!! test +Italics and possessives (1) +!! input +obtained by ''[[Lunar Prospector]]'''s gamma-ray spectrometer +!! result +<p>obtained by <i><a href="/index.php?title=Lunar_Prospector&action=edit&redlink=1" class="new" title="Lunar Prospector (page does not exist)">Lunar Prospector</a>'</i>s gamma-ray spectrometer +</p> +!! end + +# this example taken from [[en:Flaming Pie]] (bug 49926) +!! test +Italics and possessives (2) +!! input +'''''Flaming Pie''''' is ... released in 1997. In ''Flaming Pie'''s liner notes +!! result +<p><i><b>Flaming Pie</b></i> is ... released in 1997. In <i>Flaming Pie'</i>s liner notes +</p> +!! end +# this example taken from [[en:Dictionary]] (bug 49926) +!! test +Italics and possessives (3) +!! input +The first monolingual dictionary written in a Romance language was ''Sebastián Covarrubias''' ''Tesoro de la lengua castellana o española'', published in 1611 in Madrid. In 1612 the first edition of the ''Vocabolario dell'[[Accademia della Crusca]]'', for Italian, was published. In 1690 in Rotterdam was published, posthumously, the ''Dictionnaire Universel''. +!! result +<p>The first monolingual dictionary written in a Romance language was <i>Sebastián Covarrubias'</i> <i>Tesoro de la lengua castellana o española</i>, published in 1611 in Madrid. In 1612 the first edition of the <i>Vocabolario dell'<a href="/index.php?title=Accademia_della_Crusca&action=edit&redlink=1" class="new" title="Accademia della Crusca (page does not exist)">Accademia della Crusca</a></i>, for Italian, was published. In 1690 in Rotterdam was published, posthumously, the <i>Dictionnaire Universel</i>. +</p> !! end + ### ### 2-quote opening sequence tests ### @@ -258,13 +532,26 @@ Italics and bold: 2-quote opening sequence: (2,4) !! test -Italics and bold: 2-quote opening sequence: (2,5) +Italics and bold: 2-quote opening sequence: (2,5) (php) +!! options +php !! input ''foo''''' !! result <p><i>foo</i> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 2-quote opening sequence: (2,5) (parsoid) +!! options +parsoid +!! input +''foo''''' +!! result +<p><i>foo</i><b></b> +</p> +!!end ### @@ -302,13 +589,26 @@ Italics and bold: 3-quote opening sequence: (3,4) !! test -Italics and bold: 3-quote opening sequence: (3,5) +Italics and bold: 3-quote opening sequence: (3,5) (php) +!! options +php !! input '''foo''''' !! result <p><b>foo</b> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 3-quote opening sequence: (3,5) (parsoid) +!! options +parsoid +!! input +'''foo''''' +!! result +<p><b>foo</b><i></i> +</p> +!!end ### @@ -346,13 +646,26 @@ Italics and bold: 4-quote opening sequence: (4,4) !! test -Italics and bold: 4-quote opening sequence: (4,5) +Italics and bold: 4-quote opening sequence: (4,5) (php) +!! options +php !! input ''''foo''''' !! result <p>'<b>foo</b> </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: 4-quote opening sequence: (4,5) (parsoid) +!! options +parsoid +!! input +''''foo''''' +!! result +<p>'<b>foo</b><i></i> +</p> +!!end ### @@ -361,6 +674,7 @@ Italics and bold: 4-quote opening sequence: (4,5) !! test Italics and bold: 5-quote opening sequence: (5,2) +!! options !! input '''''foo'' !! result @@ -432,23 +746,49 @@ Italics and bold: multiple quote sequences: (2,4,4) !! test -Italics and bold: multiple quote sequences: (3,4,2) +Italics and bold: multiple quote sequences: (3,4,2) (php) +!! options +php !! input '''foo''''bar'' !! result <p><b>foo'</b>bar </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: multiple quote sequences: (3,4,2) (parsoid) +!! options +parsoid +!! input +'''foo''''bar'' +!! result +<p><b>foo'</b>bar<i></i> +</p> +!!end !! test -Italics and bold: multiple quote sequences: (3,4,3) +Italics and bold: multiple quote sequences: (3,4,3) (php) +!! options +php !! input '''foo''''bar''' !! result <p><b>foo'</b>bar </p> !!end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +Italics and bold: multiple quote sequences: (3,4,3) (parsoid) +!! options +parsoid +!! input +'''foo''''bar''' +!! result +<p><b>foo'</b>bar<b></b> +</p> +!!end ### ### other quote tests @@ -485,6 +825,7 @@ Italics and bold: other quote tests: (3,2,3,2) !! test Italics and bold: other quote tests: (3,2,3,3) +!! options !! input '''this is about ''foo'''s family''' !! result @@ -512,6 +853,23 @@ The ''[[Main Page]]'''s talk page. </p> !! end +!! test +Parsoid only: Quote balancing context should be restricted to td/th cells on the same wikitext line +(Requires tidy for PHP parser output to be fixed up) +!! options +parsoid=wt2html,wt2wt +!! input +{| +!''a!!''b +|''a||''b +|} +!! result +<table> +<tbody><tr><th><i>a</i></th><th><i>b</i></th> +<td><i>a</i></td><td><i>b</i></td></tr> +</tbody></table> +!! end + ### ### Non-html5 tags ### @@ -533,6 +891,74 @@ Non-html5 tags should be accepted </p> !! end +!! test +<wbr> is valid wikitext (bug 52468) +!! input +<wbr> +!! result +<p><wbr /> +</p> +!! end + +# <strike> is HTML4, <s> is HTML4/5. +!! test +<s> or <strike> for strikethrough +!! input +<strike>strike</strike> + +<s>s</s> +!! result +<p><strike>strike</strike> +</p><p><s>s</s> +</p> +!! end + +!! test +Non-word characters don't terminate tag names (bug 17663, 40670, 52022) +!! input +<b→> doesn't work! </b> + +<bä> doesn't work! </b> + +<boo> works fine </b> + +<s.foo>foo</s> + +<s.foo>s.foo</s.foo> + +<sub-ID#1> +!! result +<p><b→> doesn't work! </b> +</p><p><bä> doesn't work! </b> +</p><p><boo> works fine </b> +</p><p><s.foo>foo</s> +</p><p><s.foo>s.foo</s.foo> +</p><p><sub-ID#1> +</p> +!! end + +### +### Special characters +### + +!! test +Bare pipe character (bug 52363) +!! input +| +!! result +<p>| +</p> +!! end + +!! test +Bare pipe character from a template (bug 52363) +!! input +{{pipe}} +!! result +<p>| +</p> +!! end + ### ### <nowiki> test cases ### @@ -579,15 +1005,24 @@ nowiki 3 *There is not nowiki. *There is <nowiki>nowiki</nowiki>. !! result -<dl><dd>There is not nowiki. -</dd><dd>There is nowiki. -</dd></dl> -<ol><li>There is not nowiki. -</li><li>There is nowiki. -</li></ol> -<ul><li>There is not nowiki. -</li><li>There is nowiki. -</li></ul> +<dl> +<dd>There is not nowiki. +</dd> +<dd>There is nowiki. +</dd> +</dl> +<ol> +<li>There is not nowiki. +</li> +<li>There is nowiki. +</li> +</ol> +<ul> +<li>There is not nowiki. +</li> +<li>There is nowiki. +</li> +</ul> !! end @@ -600,6 +1035,16 @@ Entities inside <nowiki> </p> !! end +!! test +Entities inside template parameters +!! options +parsoid +!! input +{{echo|–}} +!! result +<p><span typeof="mw:Transclusion mw:Entity" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&ndash;"}},"i":0}}]}'>–</span> +</p> +!! end ### ### Comments @@ -781,7 +1226,7 @@ b !! end ### -### paragraph wraping tests +### paragraph wrapping tests ### !! test No block tags @@ -794,8 +1239,9 @@ b </p><p>b </p> !! end + !! test -Block tag on one line +Block tag on one line (<div>) !! input a <div>foo</div> @@ -807,7 +1253,19 @@ a <div>foo</div> !! end !! test -Block tag on both lines +Block tag on one line (<blockquote>) +!! input +a <blockquote>foo</blockquote> + +b +!! result +a <blockquote>foo</blockquote> +<p>b +</p> +!! end + +!! test +Block tag on both lines (<div>) !! input a <div>foo</div> @@ -819,6 +1277,18 @@ b <div>foo</div> !! end !! test +Block tag on both lines (<blockquote>) +!! input +a <blockquote>foo</blockquote> + +b <blockquote>foo</blockquote> +!! result +a <blockquote>foo</blockquote> +b <blockquote>foo</blockquote> + +!! end + +!! test Multiple lines without block tags !! input <div>foo</div> a @@ -837,7 +1307,7 @@ x <div>foo</div> z !! end !! test -Empty lines between block tags to test open p-tags are closed between the block tags +Empty lines between lines with block tags !! input <div></div> @@ -845,6 +1315,12 @@ Empty lines between block tags to test open p-tags are closed between the block <div></div>a b +<div>a</div>b + +<div>b</div>d + + +<div>e</div> !! result <div></div> <p><br /> @@ -852,6 +1328,12 @@ b <div></div>a <p>b </p> +<div>a</div>b +<div>b</div>d +<p><br /> +</p> +<div>e</div> + !! end ### @@ -875,6 +1357,22 @@ And a <a href="/wiki/Main_Page" title="Main Page">link</a> !! end !! test +Tabs don't trigger preformatted text +!! input + This is not + preformatted text. + This is preformatted text. + So is this. +!! result +<p> This is not + preformatted text. +</p> +<pre>This is preformatted text. + So is this. +</pre> +!! end + +!! test Ident preformatting with inline content !! input a @@ -916,17 +1414,61 @@ Regression with preformatted in <center> !! end -# Expected output in the following test is not really expected (there should be -# <pre> in the output) -- it's only testing for well-formedness. !! test -Bug 6200: Preformatted in <blockquote> +Bug 52763: Preformatted in <blockquote> !! input <blockquote> Blah </blockquote> !! result <blockquote> - Blah +<p> Blah +</p> +</blockquote> + +!! end + +!! test +Bug 51086: Double newlines in blockquotes should be turned into paragraphs +!! input +<blockquote> +Foo + +Bar +</blockquote> +!! result +<blockquote> +<p>Foo +</p><p>Bar +</p> +</blockquote> + +!! end + +!! test +Bug 15491: <ins>/<del> in blockquote +!! input +<blockquote> +Foo <del>bar</del> <ins>baz</ins> quux +</blockquote> +!! result +<blockquote> +<p>Foo <del>bar</del> <ins>baz</ins> quux +</p> +</blockquote> + +!! end + +# Note that the p-wrapping is newline sensitive, which could be +# considered a bug: tidy will wrap only the 'Foo' in the example +# below in a <p> tag. (see comment 23-25 of bug #6200) +!! test +Bug 15491: <ins>/<del> in blockquote (2) +!! input +<blockquote>Foo <del>bar</del> <ins>baz</ins> quux +</blockquote> +!! result +<blockquote>Foo <del>bar</del> <ins>baz</ins> quux </blockquote> !! end @@ -1156,53 +1698,224 @@ Templates: Indent-Pre: 1f: Wrapping should be based on expanded content </pre> !!end +# TODO / maybe: fix wt2wt for this !! test -Templates: Single-line variant of parameter whitespace stripping test +Parsoid: Don't paragraph-wrap fosterable content +!! options +parsoid=wt2html !! input -{{echo| a}} +{| +<td></td> +<td></td> -{{echo|1= a}} -{{echo|{{echo| a}}}} -{{echo|1={{echo| a}}}} +|} +!! result +<table> + +<tbody> +<tr> +<td></td> + +<td></td></tr> + + + +</tbody></table> +!! end + +!! test +Parsoid: Don't paragraph-wrap fosterable content even if table syntax is unbalanced +!! options +parsoid=wt2html +!! input +{| +<td> +<td> +</td> + + + +|} +!! result +<table> + +<tbody> +<tr> +<td></td> + +<td> +</td></tr> + + + +</tbody></table> +!! end + + +#-------------------------------------------------------------------- +# Transclusion parameter whitespace stripping tests +# Behavior is different for positional and named parameters +#-------------------------------------------------------------------- +!! test +Templates: Strip leading and trailing whitespace from named-param values +!! input +{{echo|1= a }} + +{{echo|1= {{echo|b}} }} + +{{echo| 1 = + c }} + +{{echo| 1 = +* d +}} !! result -<pre>a -</pre> -<p>a -</p> -<pre>a -</pre> <p>a +</p><p>b +</p><p>c </p> +<ul> +<li> d +</li> +</ul> + !! end !! test -Templates: Strip whitespace from named parameters, but not positional ones +Templates: Don't strip whitespace from positional-param values !! input -{{echo| - foo}} +{{echo|a }} + +{{echo|{{echo|b}} }} + +{{echo| c +}} + +{{echo| {{echo|d}} +}} {{echo| -* foo}} + e}} -{{echo| 1 = - foo}} +{{echo| +* f}} -{{echo| 1 = -* foo}} +{{echo| + }}g !! result -<pre>foo +<p>a +</p><p>b +</p> +<pre>c </pre> <p><br /> </p> -<ul><li> foo -</li></ul> +<pre>d +</pre> +<p><br /> +</p> +<pre>e +</pre> +<p><br /> +</p> +<ul> +<li> f +</li> +</ul> +<p><br /> +</p> +<pre>g +</pre> +!! end + +!! test +Templates: Handle empty comment-and-ws-only lines correctly +!! input +{{echo|foo +<!--should be ignored--> + <!--should be ignored as well--> +bar}} +!! result <p>foo +bar </p> -<ul><li> foo -</li></ul> +!! end +#-------------------------------------------------------------------- +# Transclusion parameter escaping tests +#-------------------------------------------------------------------- +!! test +Templates: Parsoid parameter escaping test 1 +!! options +parsoid +!! input +{{echo|[foo]|{{echo|[bar]}}}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[foo]"},"2":{"wt":"{{echo|[bar]}}"}},"i":0}}]}'>[foo]</p> +!! end + +!! test +Parsoid: Pipes in external links in template parameter +!! options +parsoid +!! input +{{echo|[{{echo|http://example.com}} link]}} +!! result +<p><a rel="mw:ExtLink" href="http://example.com" about="#mwt31" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[{{echo|http://example.com}} link]"}},"i":0}}]}'>link</a></p> +!! end + +!! test +Parsoid: pipe in transclusion parameter +!! options +parsoid +!! input +{{echo|http://foo.com/a|b}} +!! result +<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1" +typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://foo.com/a&#124;b"}},"i":0}}]}'>http://foo.com/a|b</a></p> +!! end + +!! test +Parsoid: Pipe in external link target and content in template parameter +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|[http://foo.com/a|b a|b]}} +!! result +<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1" +typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"}, +"params":{"1":{"wt":"[http://foo.com/a|b a|b]"}},"i":0}}]}'>a|b</a></p> +!! end + +!! test +Templates: Dont escape already nowiki-escaped text in template parameters +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|foo<nowiki>|</nowiki>bar}} +{{echo|<nowiki><div></nowiki>}} +{{echo|<nowiki></nowiki>}} +!! result +<p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo<nowiki>|</nowiki>bar"}},"i":0}}]}'}'>foo</span><span typeof="mw:Nowiki" about="#mwt1">|</span><span about="#mwt1">bar</span> +<span typeof="mw:Transclusion mw:Nowiki" about="#mwt2" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki>&lt;div&gt;</nowiki>"}},"i":0}}]}'><span typeof="mw:Entity"><</span>div<span typeof="mw:Entity">></span></span> +<span typeof="mw:Transclusion mw:Nowiki" about="#mwt3" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<nowiki></nowiki>"}},"i":0}}]}'></span> +</p> +!! end + +## Bug 52824 +!! test +Templates: '=' char in nested transclusions should not trigger nowiki escapes or conversion to named param +!! options +parsoid=html2wt,wt2wt +!! input +{{echo|{{echo|1=bar}}}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{echo|1=bar}}"}},"i":0}}]}'>bar</p> !! end ### @@ -1249,6 +1962,20 @@ c !!end !!test +1d. Indent-Pre and Comments +(Pre-handler currently cannot distinguish between comment/ws order and normalizes them to [comment,ws] order) +!!input +<!--a--> a + + <!--b-->b +!!result +<pre>a +</pre> +<pre>b +</pre> +!!end + +!!test 2a. Indent-Pre and tables !!input {| @@ -1307,10 +2034,12 @@ c !!input <p> foo </p> <div> foo </div> + <blockquote> foo </blockquote> <span> foo </span> !!result <p> foo </p> <div> foo </div> + <blockquote> foo </blockquote> <pre><span> foo </span> </pre> !!end @@ -1334,6 +2063,12 @@ c foo </blockquote> +<blockquote> +<pre> +foo +</pre> +</blockquote> + <table><tr><td> foo </td></tr></table> @@ -1355,7 +2090,13 @@ c </pre> </center> <blockquote> - foo +<p> foo +</p> +</blockquote> +<blockquote> +<pre> +foo +</pre> </blockquote> <table><tr><td> <pre>foo @@ -1400,6 +2141,56 @@ b </pre> !! end +!! test +6. Pre-blocks should extend across lines with leading WS even when there is no wrappable content +!! input + a + + <!-- continue --> + b + + c + +d +!! result +<pre>a + +b +</pre> +<pre>c + +</pre> +<p>d +</p> +!! end + +!! test +7a. Indent-pre and category links +!! options +parsoid=wt2html,wt2wt +!! input + [[Category:foo]] <!-- No pre-wrapping --> +{{echo| [[Category:foo]]}} <!-- No pre-wrapping --> +!! result + <link rel="mw:WikiLink/Category" href="./Category:Foo"> <!-- No pre-wrapping --> +<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" [[Category:foo]]"}},"i":0}}]}'> </span> +<link rel="mw:WikiLink/Category" href="./Category:Foo" about="#mwt1"> <!-- No pre-wrapping --> +!! end + +!! test +7b. Indent-pre and category links +!! options +parsoid=wt2html,wt2wt +!! input + [[Category:foo]] a + [[Category:foo]] {{echo|b}} +!! result +<pre> +<link rel="mw:WikiLink/Category" href="./Category:Foo"> a + +<link rel="mw:WikiLink/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> +!! end + ### ### HTML-pre (some to spec PHP parser behavior and some Parsoid-RT-centric) ### @@ -1482,8 +2273,11 @@ Simple definition !! input ; name : Definition !! result -<dl><dt> name </dt><dd> Definition -</dd></dl> +<dl> +<dt> name </dt> +<dd> Definition +</dd> +</dl> !! end @@ -1492,8 +2286,10 @@ Definition list for indentation only !! input : Indented text !! result -<dl><dd> Indented text -</dd></dl> +<dl> +<dd> Indented text +</dd> +</dl> !! end @@ -1502,8 +2298,11 @@ Definition list with no space !! input ;name:Definition !! result -<dl><dt>name</dt><dd>Definition -</dd></dl> +<dl> +<dt>name</dt> +<dd>Definition +</dd> +</dl> !!end @@ -1512,8 +2311,11 @@ Definition list with URL link !! input ; http://example.com/ : definition !! result -<dl><dt> <a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> </dt><dd> definition -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> </dt> +<dd> definition +</dd> +</dl> !! end @@ -1522,8 +2324,11 @@ Definition list with bracketed URL link !! input ;[http://www.example.com/ Example]:Something about it !! result -<dl><dt><a rel="nofollow" class="external text" href="http://www.example.com/">Example</a></dt><dd>Something about it -</dd></dl> +<dl> +<dt><a rel="nofollow" class="external text" href="http://www.example.com/">Example</a></dt> +<dd>Something about it +</dd> +</dl> !! end @@ -1532,8 +2337,11 @@ Definition list with wikilink containing colon !! input ; [[Help:FAQ]]: The least-read page on Wikipedia !! result -<dl><dt> <a href="/index.php?title=Help:FAQ&action=edit&redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt><dd> The least-read page on Wikipedia -</dd></dl> +<dl> +<dt> <a href="/index.php?title=Help:FAQ&action=edit&redlink=1" class="new" title="Help:FAQ (page does not exist)">Help:FAQ</a></dt> +<dd> The least-read page on Wikipedia +</dd> +</dl> !! end @@ -1543,8 +2351,11 @@ Definition list with news link containing colon !! input ; news:alt.wikipedia.rox: This isn't even a real newsgroup! !! result -<dl><dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt><dd> This isn't even a real newsgroup! -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a></dt> +<dd> This isn't even a real newsgroup! +</dd> +</dl> !! end @@ -1553,8 +2364,10 @@ Malformed definition list with colon !! input ; news:alt.wikipedia.rox -- don't crash or enter an infinite loop !! result -<dl><dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop -</dt></dl> +<dl> +<dt> <a rel="nofollow" class="external free" href="news:alt.wikipedia.rox">news:alt.wikipedia.rox</a> -- don't crash or enter an infinite loop +</dt> +</dl> !! end @@ -1563,8 +2376,11 @@ Definition lists: colon in external link text !! input ; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up !! result -<dl><dt> <a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia : The Next Generation</a></dt><dd> OK, I made that up -</dd></dl> +<dl> +<dt> <a rel="nofollow" class="external text" href="http://www.wikipedia2.org/">Wikipedia : The Next Generation</a></dt> +<dd> OK, I made that up +</dd> +</dl> !! end @@ -1573,8 +2389,10 @@ Definition lists: colon in HTML attribute !! input ;<b style="display: inline">bold</b> !! result -<dl><dt><b style="display: inline">bold</b> -</dt></dl> +<dl> +<dt><b style="display: inline">bold</b> +</dt> +</dl> !! end @@ -1583,8 +2401,11 @@ Definition lists: self-closed tag !! input ;one<br/>two : two-line fun !! result -<dl><dt>one<br />two </dt><dd> two-line fun -</dd></dl> +<dl> +<dt>one<br />two </dt> +<dd> two-line fun +</dd> +</dl> !! end @@ -1613,16 +2434,19 @@ Definition and unordered list using wiki syntax nested in unordered list using h <ul><li> ; term : description * unordered -</li> -</ul> +</li></ul> !! result <ul><li> -<dl><dt> term </dt><dd> description -</dd></dl> -<ul><li> unordered -</li></ul> +<dl> +<dt> term </dt> +<dd> description +</dd> +</dl> +<ul> +<li> unordered </li> </ul> +</li></ul> !! end @@ -1633,8 +2457,11 @@ Definition list with empty definition and following paragraph ; term: Paragraph text !! result -<dl><dt> term</dt><dd> -</dd></dl> +<dl> +<dt> term</dt> +<dd> +</dd> +</dl> <p>Paragraph text </p> !! end @@ -1663,10 +2490,14 @@ Definition Lists: No nesting: Multiple dd's :a :b !! result -<dl><dt>x -</dt><dd>a -</dd><dd>b -</dd></dl> +<dl> +<dt>x +</dt> +<dd>a +</dd> +<dd>b +</dd> +</dl> !! end @@ -1677,12 +2508,18 @@ Definition Lists: Indentation: Regular ::i2 :::i3 !! result -<dl><dd>i1 -<dl><dd>i2 -<dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd>i1 +<dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1692,11 +2529,17 @@ Definition Lists: Indentation: Missing 1st level ::i2 :::i3 !! result -<dl><dd><dl><dd>i2 -<dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1705,10 +2548,16 @@ Definition Lists: Indentation: Multi-level indent !! input :::i3 !! result -<dl><dd><dl><dd><dl><dd>i3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd><dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end @@ -1732,6 +2581,21 @@ should be left alone should be left alone </p> !! end + +# Bug 52473 +!! test +Definition Lists: Hacky use to indent tables (WS-insensitive) +!! options +parsoid +!! input +: {| +|a +|} +!! result +<dl> +<dd> <table><tr><td>a</td></tr></table> </dd> +</dl> +!! 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 @@ -1783,13 +2647,17 @@ Table / list interaction: indented table with lists in table contents <tr> <td> a -<ul><li> b -</li></ul> +<ul> +<li> b +</li> +</ul> </td></tr> <tr> <td> c -<ul><li> d -</li></ul> +<ul> +<li> d +</li> +</ul> </td></tr></table></dd></dl> !! end @@ -1812,18 +2680,27 @@ Table / list interaction: lists nested in tables nested in indented lists <dl><dd><table> <tr> <td> -<dl><dd>a -</dd><dd>b -</dd></dl> +<dl> +<dd>a +</dd> +<dd>b +</dd> +</dl> </td> <td> -<ul><li>c -</li><li>d -</li></ul> +<ul> +<li>c +</li> +<li>d +</li> +</ul> </td></tr></table></dd></dl> -<ul><li>e -</li><li>f -</li></ul> +<ul> +<li>e +</li> +<li>f +</li> +</ul> !!end @@ -1911,32 +2788,75 @@ Definition Lists: Nesting: Test 4 ::;t3 :::d3 !! result -<dl><dd><dl><dd><dl><dt>t3 -</dt><dd>d3 -</dd></dl> -</dd></dl> -</dd></dl> +<dl> +<dd><dl> +<dd><dl> +<dt>t3 +</dt> +<dd>d3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> !! end +## The Parsoid team believes the following three test exposes a +## bug in the PHP parser. (Parsoid team thinks the PHP parser is +## wrong to close the <dl> after the <dt> containing the <ul>.) !! test -Definition Lists: Mixed Lists: Test 1 +Definition Lists: Mixed Lists: Test 1 (php) +!! options +php !! input :;* foo ::* bar :; baz !! result -<dl><dd><dl><dt><ul><li> foo -</li><li> bar -</li></ul> -</dt></dl> -<dl><dt> baz -</dt></dl> -</dd></dl> +<dl> +<dd><dl> +<dt><ul> +<li> foo +</li> +<li> bar +</li> +</ul> +</dt> +</dl> +<dl> +<dt> baz +</dt> +</dl> +</dd> +</dl> !! end - +!! test +Definition Lists: Mixed Lists: Test 1 (parsoid) +!! options +parsoid +!! input +:;* foo +::* bar +:; baz +!! result +<dl> +<dd><dl> +<dt><ul> +<li> foo +</li> +</ul></dt> +<dd><ul> +<li> bar +</li> +</ul></dd> +<dt> baz</dt> +</dl></dd> +</dl> +!! end !! test Definition Lists: Mixed Lists: Test 2 @@ -1944,10 +2864,15 @@ Definition Lists: Mixed Lists: Test 2 *: d1 *: d2 !! result -<ul><li><dl><dd> d1 -</dd><dd> d2 -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</li> +</ul> !! end @@ -1958,12 +2883,21 @@ Definition Lists: Mixed Lists: Test 3 *::: d1 *::: d2 !! result -<ul><li><dl><dd><dl><dd><dl><dd> d1 -</dd><dd> d2 -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd><dl> +<dd><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> !! end @@ -1974,10 +2908,17 @@ Definition Lists: Mixed Lists: Test 4 *;d1 :d2 *;d3 :d4 !! result -<ul><li><dl><dt>d1 </dt><dd>d2 -</dd><dt>d3 </dt><dd>d4 -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dt>d1 </dt> +<dd>d2 +</dd> +<dt>d3 </dt> +<dd>d4 +</dd> +</dl> +</li> +</ul> !! end @@ -1988,11 +2929,17 @@ Definition Lists: Mixed Lists: Test 5 *:d1 *:: d2 !! result -<ul><li><dl><dd>d1 -<dl><dd> d2 -</dd></dl> -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dd>d1 +<dl> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</li> +</ul> !! end @@ -2003,13 +2950,23 @@ Definition Lists: Mixed Lists: Test 6 #*:d1 #*::: d3 !! result -<ol><li><ul><li><dl><dd>d1 -<dl><dd><dl><dd> d3 -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> -</li></ol> +<ol> +<li><ul> +<li><dl> +<dd>d1 +<dl> +<dd><dl> +<dd> d3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> +</li> +</ol> !! end @@ -2020,10 +2977,15 @@ Definition Lists: Mixed Lists: Test 7 :* d1 :* d2 !! result -<dl><dd><ul><li> d1 -</li><li> d2 -</li></ul> -</dd></dl> +<dl> +<dd><ul> +<li> d1 +</li> +<li> d2 +</li> +</ul> +</dd> +</dl> !! end @@ -2034,12 +2996,20 @@ Definition Lists: Mixed Lists: Test 8 :* d1 ::* d2 !! result -<dl><dd><ul><li> d1 -</li></ul> -<dl><dd><ul><li> d2 -</li></ul> -</dd></dl> -</dd></dl> +<dl> +<dd><ul> +<li> d1 +</li> +</ul> +<dl> +<dd><ul> +<li> d2 +</li> +</ul> +</dd> +</dl> +</dd> +</dl> !! end @@ -2049,9 +3019,14 @@ Definition Lists: Mixed Lists: Test 9 !! input *;foo :bar !! result -<ul><li><dl><dt>foo </dt><dd>bar -</dd></dl> -</li></ul> +<ul> +<li><dl> +<dt>foo </dt> +<dd>bar +</dd> +</dl> +</li> +</ul> !! end @@ -2061,51 +3036,172 @@ Definition Lists: Mixed Lists: Test 10 !! input *#;foo :bar !! result -<ul><li><ol><li><dl><dt>foo </dt><dd>bar -</dd></dl> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><dl> +<dt>foo </dt> +<dd>bar +</dd> +</dl> +</li> +</ol> +</li> +</ul> !! end +# The Parsoid team disagrees with the PHP parser's seemingly-random +# rules regarding dd/dt on the next two tests. Parsoid is more +# consistent, and recognizes the shared nesting and keeps the +# still-open tags around until the nesting is complete. !! test -Definition Lists: Mixed Lists: Test 11 +Definition Lists: Mixed Lists: Test 11 (php) +!! options +php !! input *#*#;*;;foo :bar *#*#;boo :baz !! result -<ul><li><ol><li><ul><li><ol><li><dl><dt>foo </dt><dd><ul><li><dl><dt><dl><dt>bar -</dt></dl> -</dd></dl> -</li></ul> -</dd></dl> -<dl><dt>boo </dt><dd>baz -</dd></dl> -</li></ol> -</li></ul> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><ul> +<li><ol> +<li><dl> +<dt>foo </dt> +<dd><ul> +<li><dl> +<dt><dl> +<dt>bar +</dt> +</dl> +</dd> +</dl> +</li> +</ul> +</dd> +</dl> +<dl> +<dt>boo </dt> +<dd>baz +</dd> +</dl> +</li> +</ol> +</li> +</ul> +</li> +</ol> +</li> +</ul> !! end +!! test +Definition Lists: Mixed Lists: Test 11 (parsoid) +!! options +parsoid +!! input +*#*#;*;;foo :bar +*#*#;boo :baz +!! result +<ul> +<li> +<ol> +<li> +<ul> +<li> +<ol> +<li> +<dl> +<dt> +<ul> +<li> +<dl> +<dt> +<dl> +<dt>foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'>bar</dd> +</dl></dt> +</dl></li> +</ul></dt> +<dt>boo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'>baz</dd> +</dl></li> +</ol></li> +</ul></li> +</ol></li> +</ul> +!! end !! test -Definition Lists: Weird Ones: Test 1 +Definition Lists: Weird Ones: Test 1 (php) +!! options +php !! input *#;*::;; foo : bar (who uses this?) !! result -<ul><li><ol><li><dl><dt> foo </dt><dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt> bar (who uses this?) -</dt></dl> -</dd></dl> -</dd></dl> -</dd></dl> -</li></ul> -</dd></dl> -</li></ol> -</li></ul> +<ul> +<li><ol> +<li><dl> +<dt> foo </dt> +<dd><ul> +<li><dl> +<dd><dl> +<dd><dl> +<dt><dl> +<dt> bar (who uses this?) +</dt> +</dl> +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> +</dd> +</dl> +</li> +</ol> +</li> +</ul> !! end +!! test +Definition Lists: Weird Ones: Test 1 (parsoid) +!! options +parsoid +!! input +*#;*::;; foo : bar (who uses this?) +!! result +<ul> +<li> +<ol> +<li> +<dl> +<dt> +<ul> +<li> +<dl> +<dd> +<dl> +<dd> +<dl> +<dt> +<dl> +<dt> foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'> </span></dt> +<dd data-parsoid='{"stx":"row"}'> bar (who uses this?)</dd> +</dl></dt> +</dl></dd> +</dl></dd> +</dl></li> +</ul></dt> +</dl></li> +</ol></li> +</ul> +!! end ### ### External links @@ -2270,6 +3366,17 @@ External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png !! end !! test +External image (when not allowed) +!! options +wgAllowExternalImages=0 +!! input +External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png +!! result +<p>External image: <a rel="nofollow" class="external free" href="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png">http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png</a> +</p> +!! end + +!! test Link to non-http image, no img tag !! input Link to non-http image, no img tag: ftp://example.com/test.jpg @@ -2692,6 +3799,15 @@ External link containing double-single-quotes with no space separating the url f !! end !! test +External link with comments in link text +!! input +[http://www.google.com Google <!-- comment -->] +!! result +<p><a rel="nofollow" class="external text" href="http://www.google.com">Google </a> +</p> +!! end + +!! test URL-encoding in URL functions (single parameter) !! input {{localurl:Some page|amp=&}} @@ -2763,6 +3879,28 @@ Non-extlinks in brackets </p> !! end +!! test +Parsoid: Percent encoding in external links +!! options +parsoid +!! input +[https://github.com/search?l=&q=ResourceLoader+%40wikimedia Search] +!! result +<p><a rel="mw:ExtLink" +href="https://github.com/search?l=&q=ResourceLoader+%40wikimedia">Search</a></p> +!! end + +!! test +Parsoid: use url link syntax for links where the content is equal the link +target +!! options +parsoid +!! input +http://example.com +!! result +<p><a rel="mw:ExtLink" href="http://example.com">http://example.com</a></p> +!! end + ### ### Quotes ### @@ -2781,7 +3919,9 @@ Normal text. '''''Bold italic text.''''' Normal text. !! test -Unclosed and unmatched quotes +Unclosed and unmatched quotes (php) +!! options +php !! input '''''Bold italic text '''with bold deactivated''' in between.''''' @@ -2816,6 +3956,47 @@ Plain ''italic'''s plain </p><p>Plain <i>italic'</i>s plain </p> !! end +# Parsoid inserts an empty bold tag pair at the end of the line, that the PHP +# parser strips. The wikitext contains just the first half of the bold +# quote pair. +!! test +Unclosed and unmatched quotes (parsoid) +!! options +parsoid +!! 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. + +<!-- Unmatching number of opening, closing tags: --> +'''This year''''s election ''should'' beat '''last year''''s. + +''Tom'''s car is bigger than ''Susan'''s. + +Plain ''italic'''s plain +!! result +<p><i><b>Bold italic text </b>with bold deactivated<b> in between.</b></i> +</p><p><b><i>Bold italic text </i>with italic deactivated<i> in between.</i></b> +</p><p><b>Bold text..</b> +</p><p>..spanning two paragraphs (should not work).<b></b> +</p><p><b>Bold tag left open</b> +</p><p><i>Italic tag left open</i> +</p><p>Normal text. +</p><p><b>This year'</b>s election <i>should</i> beat <b>last year'</b>s. +</p><p><i>Tom<b>s car is bigger than </b></i><b>Susan</b>s. +</p><p>Plain <i>italic'</i>s plain +</p> +!! end ### ### Tables @@ -2824,19 +4005,33 @@ Plain ''italic'''s plain ### # This should not produce <table></table> as <table><tr><td></td></tr></table> -# is the bare minimun required by the spec, see: +# is the bare minimum 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. +A table with no data. (php) +!! options +php +!! input +{||} +!! result +!! end +# Parsoid team replies: empty table tags are legal in HTML5 +!! test +A table with no data. (parsoid) +!! options +parsoid !! input {||} !! result +<table></table> !! end # A table with nothing but a caption is invalid XHTML, we might want to render # this as <p>caption</p> !! test -A table with nothing but a caption +A table with nothing but a caption (php) +!! options +php !! input {| |+ caption @@ -2847,6 +4042,18 @@ A table with nothing but a caption </caption><tr><td></td></tr></table> !! end +# Parsoid team replies: table with only a caption is legal in HTML5 +!! test +A table with nothing but a caption (parsoid) +!! options +parsoid +!! input +{| +|+ caption +|} +!! result +<table><caption> caption</caption></table> +!! end !! test A table with caption with default-spaced attributes and a table row @@ -3243,11 +4450,44 @@ Template-generated table cell attributes and cell content !! input {| |{{table_attribs}} +| {{table_attribs}} |} !! result <table> <tr> <td style="color: red"> Foo +</td> +<td style="color: red"> Foo +</td></tr></table> + +!! end + +!! test +Template-generated table cell attributes and cell content (2) +!! input +{| +|align=center {{table_attribs}} +|} +!! result +<table> +<tr> +<td align="center" style="color: red"> Foo +</td></tr></table> + +!! end + +!! test +Template-generated table cell attributes and cell content (3) +!! input +{| +|align=center {{table_cells}} +|} +!! result +<table> +<tr> +<td align="center" style="color: red"> Foo </td> +<td> Bar </td> +<td> Baz </td></tr></table> !! end @@ -3270,21 +4510,40 @@ Table with row followed by newlines and table heading !! end +!! test +Table with empty line following the start tag +!! input +{| + +|- +| foo +|} +!! result +<table> + + +<tr> +<td> foo +</td></tr></table> + +!! end + # FIXME: Preserve the attribute properly (with an empty string as value) in # the PHP parser. Parsoid implements the behavior below. !! test Table attributes with empty value !! options -disabled +parsoid !! input {| | style=| hello |} !! result <table> +<tbody> <tr> <td style=""> hello -</td></tr></table> +</td></tr></tbody></table> !! end @@ -3311,6 +4570,159 @@ Wikitext table with a lot of comments !! end +!! test +Wikitext table with double-line table cell +!! input +{| +|a +b +|} +!! result +<table> +<tr> +<td>a +<p>b +</p> +</td></tr></table> + +!! end + +!! test +Table cell with a single comment +!! input +{| +| <!-- c1 --> +| a +|} +!! result +<table> +<tr> +<td> +</td> +<td> a +</td></tr></table> + +!! end + +# The expected HTML structure in this test is debatable. The PHP parser does +# not parse this kind of table at all. The main focus for Parsoid is on +# round-tripping, so this output is ok for now. TODO: revisit! +!! test +Wikitext table with html-syntax row (Parsoid) +!! options +parsoid +!! input +{| +|- +<td>foo</td> +|} +!! result +<table> +<tbody> +<tr> +<td>foo</td></tr></tbody></table> +!! end + +!! test +Implicit <td> after a |- +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +a +|} +!! result +<table> +<tr><td>a</td></tr> +</table> +!! end + +!! test +Pres should be recognized in an explicit <td> context, but not in an implicit <td> context +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +| + a +|- + b +|} +!! result +<table> +<tbody> +<tr><td><pre>a</pre></td></tr> +<tr><td> b</td></tr> +</tbody> +</table> +!! end + +!! test +Lists should be recognized in an implicit <td> context +(PHP parser relies on Tidy to add the missing <td> tags) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|- +*a +|} +!! result +<table> +<tr> +<td><ul> +<li>a</li> +</ul></td> +</tr> +</table> +!! end + +!! test +Parsoid: Round-trip tables directly followed by content (bug 51219) +!! options +parsoid=wt2html,wt2wt +!! input +{| +|foo +|} bar + +{| +|baz +|}<b>quux</b> +!! result +<table><tbody> +<tr> +<td>foo</td></tr></tbody></table> bar +<table> +<tbody> +<tr> +<td>baz</td></tr></tbody></table><b>quux</b> +!! end + +!! test +Parsoid: Default to a newline after tables in new content (bug 51219) +!! options +parsoid=html2wt +!! input +{| +|foo +|} +<nowiki> </nowiki>bar +{| +|baz +|} +'''quux''' +!! result +<table><tbody> +<tr><td>foo</td></tr></tbody></table> bar +<table><tbody> +<tr><td>baz</td></tr></tbody></table><b>quux</b> +!! end + ### ### Internal links ### @@ -3342,6 +4754,15 @@ Piped link !! end !! test +Piped link with comment in link text +!! input +[[Main Page|The Main<!--front--> Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">The Main Page</a> +</p> +!! end + +!! test Broken link !! input [[Zigzagzogzagzig]] @@ -3462,6 +4883,22 @@ Link to namespaces </p> !! end +!! article +MemoryAlpha:AlphaTest +!! text +This is an article in the MemoryAlpha namespace +(which shadows the memoryalpha interwiki link). +!! endarticle + +!! test +Namespace takes precedence over interwiki link (bug 51680) +!! input +[[MemoryAlpha:AlphaTest]] +!! result +<p><a href="/wiki/MemoryAlpha:AlphaTest" title="MemoryAlpha:AlphaTest">MemoryAlpha:AlphaTest</a> +</p> +!! end + !! test Piped link to namespace !! input @@ -3527,6 +4964,33 @@ Link containing "<#" and ">#" as a hex sequences !! end !! test +Link containing an equals sign +!! input +[[Special:BookSources/isbn=4-00-026157-6]] +!! result +<p><a href="/wiki/Special:BookSources/isbn%3D4-00-026157-6" title="Special:BookSources/isbn=4-00-026157-6">Special:BookSources/isbn=4-00-026157-6</a> +</p> +!! end + +!! article +Foo~bar +!! text +Just a test of an article title containing a tilde. +!! endarticle + +# note that links containing signatures, like [[Foo~~~~]], are +# massaged by the pre-save transform (PST) and so the tildes are never +# seen by the parser. +!! test +Link containing a tilde +!! input +[[Foo~bar]] +!! result +<p><a href="/wiki/Foo%7Ebar" title="Foo~bar">Foo~bar</a> +</p> +!! end + +!! test Link containing double-single-quotes '' (bug 4598) !! input [[Lista d''e paise d''o munno]] @@ -3787,6 +5251,69 @@ language=kaa </p> !! end +!! article +Söfnuður +!! text +Test. +!! endarticle + +!! test +Internal link with is link prefix +!! options +language=is +!! input +Aðrir mótmælenda[[söfnuður|söfnuðir]] og +!! result +<p>Aðrir <a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðir</a> og +</p> +!! end + +!! article +Mótmælendatrú +!! text +Test. +!! endarticle + +!! test +Internal link with is link trail and link prefix +!! options +language=is +!! input +[[mótmælendatrú|xxx]]ar +[[mótmælendatrú]]ar +mótmælenda[[söfnuður]] +mótmælenda[[söfnuður|söfnuðir]] +mótmælenda[[söfnuður|söfnuðir]]xxx +!! result +<p><a href="/wiki/M%C3%B3tm%C3%A6lendatr%C3%BA" title="Mótmælendatrú">xxxar</a> +<a href="/wiki/M%C3%B3tm%C3%A6lendatr%C3%BA" title="Mótmælendatrú">mótmælendatrúar</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuður</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðir</a> +<a href="/wiki/S%C3%B6fnu%C3%B0ur" title="Söfnuður">mótmælendasöfnuðirxxx</a> +</p> +!! end + +!! test +Parsoid link trail escaping +!! options +parsoid=html2wt,html2html +!! input +[[apple]]<nowiki/>s +!! result +<p><a rel="mw:WikiLink" href="Apple">apple</a>s</p> +!! end + +!! test +Parsoid link prefix escaping +!! options +language=is +parsoid=html2wt,html2html +!! input +Aðrir mótmælenda<nowiki/>[[söfnuður]] +!! result +<p>Aðrir mótmælenda<a rel="mw:WikiLink" href="Söfnuður">söfnuður</a></p> +!! end + !! test Parsoid-centric test: Whitespace in ext- and wiki-links should be preserved !! input @@ -3833,9 +5360,12 @@ Interwiki link encoding conversion (bug 1636) *[[Wikipedia:ro:Olteniţa]] *[[Wikipedia:ro:Olteniţa]] !! result -<ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> -</li><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> -</li></ul> +<ul> +<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> +</li> +<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a> +</li> +</ul> !! end @@ -3848,6 +5378,12 @@ Interwiki link with fragment (bug 2130) </p> !! end + +### +### Interlanguage links +### Language links (so that searching for '### language' matches..) +### + !! test Interlanguage link !! input @@ -3905,6 +5441,189 @@ language=ln </p> !! end +!! test +Parsoid bug 53221: Wikilinks should be properly entity-escaped +!! options +parsoid=html2wt +!! input +He&nbsp;llo [[Foo|He&nbsp;llo]] + +He&nbsp;llo [[He&nbsp;llo]] +!!result +<p>He&nbsp;llo <a href="Foo" rel="mw:WikiLink">He&nbsp;llo</a></p> +<p>He&nbsp;llo <a href="He&nbsp;llo" rel="mw:WikiLink">He&nbsp;llo</a></p> +!! end + +!! test +Parsoid: handle constructor well +!! options +parsoid +!! input +[[constructor]] + +[[constructor:foo]] +!! result +<p data-parsoid="{"dsr":[0,15,0,0]}"><a rel="mw:WikiLink" href="./Constructor" data-parsoid="{"stx":"simple","a":{"href":"./Constructor"},"sa":{"href":"constructor"},"dsr":[0,15,2,2]}">constructor</a></p> + + +<p data-parsoid="{"dsr":[17,36,0,0]}"><a rel="mw:WikiLink" href="./Foo" data-parsoid="{"stx":"simple","a":{"href":"./Foo"},"sa":{"href":"constructor:foo"},"dsr":[17,36,2,2]}">constructor:foo</a></p> +!! end + +!! test +Parsoid: recognize interlanguage links without a target page +!! options +parsoid +!! input +[[ko:]] +!! result +<p> +<link rel="mw:WikiLink/Language" href="http://ko.wikipedia.org/wiki/"></p> +!! end + +!! test +Parsoid: recognize interwiki links without a target page +!! options +parsoid +!! input +[[:ko:]] +!! result +<p><a rel="mw:WikiLink/Interwiki" href="http://ko.wikipedia.org/wiki/">ko:</a></p> +!! end + +### +### Redirects, Parsoid-only +### +!! test +Simple redirect to page +!! options +parsoid +!! input +#REDIRECT [[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Optional colon in #REDIRECT +!! options +# the colon is archaic syntax. we support it for wt2html, but we +# don't care that it roundtrips back to the modern syntax. +parsoid=wt2html,html2html +!! input +#REDIRECT:[[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Whitespace in #REDIRECT with optional colon +!! options +# the colon and gratuitous whitespace is archaic syntax. we support +# it for wt2html, but we don't care that it roundtrips back to the +# modern syntax (without extra whitespace) +parsoid=wt2html,html2html +!! input + + #REDIRECT +: +[[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Piped link in #REDIRECT +!! options +# content after piped link is ignored. we support this syntax, +# but don't care that the piped link is lost when we roundtrip this. +parsoid=wt2html +!! input +#REDIRECT [[Main Page|bar]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + +!! test +Redirect to category +!! options +parsoid=wt2html +!! input +#REDIRECT [[Category:Foo]] +!! result +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +!! end + +!! test +Redirect to category with URL encoding +!! options +parsoid=wt2html +!! input +#REDIRECT [[Category%3AFoo]] +!! result +<link rel="mw:PageProp/redirect" href="./Category:Foo"><link rel="mw:WikiLink/Category" href="./Category:Foo"> +!! end + +!! test +Redirect to category page +!! options +parsoid=wt2html,html2html +!! input +#REDIRECT [[:Category:Foo]] +!! result +<p><a rel="mw:WikiLink" href="Category:Foo">Category:Foo</a></p> +!! end + +!! test +Redirect to image page (1) +!! options +parsoid +!! input +#REDIRECT [[File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="./File:Wiki.png"> +!! end + +!! test +Redirect to image page (2) +!! options +parsoid +!! input +#REDIRECT [[Image:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="./File:Wiki.png"> +!! end + +!! test +Redirect to language +!! options +parsoid +!! input +#REDIRECT [[en:File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="File:Wiki.png"> +!! end + +!! test +Redirect to interwiki +!! options +parsoid +!! input +#REDIRECT [[meatball:File:Wiki.png]] +!! result +<link rel="mw:PageProp/redirect" href="File:Wiki.png"> +!! end + +!! test +Non-English #REDIRECT +!! options +parsoid +language=is +!! input +#TILVÍSUN [[Main Page]] +!! result +<link rel="mw:PageProp/redirect" href="./Main_Page"> +!! end + ## ## XHTML tidiness ### @@ -3920,6 +5639,8 @@ language=ln !! test Broken br tag sanitization +!! options +php !! input </br> !! result @@ -3927,6 +5648,17 @@ Broken br tag sanitization </p> !! end +# TODO: Fix html2html mode (bug 51055)! +!! test +Parsoid: Broken br tag recognition +!! options +parsoid=wt2html +!! input +</br> +!! result +<p><br></p> +!! end + !! test Incorrecly removing closing slashes from correctly formed XHTML !! input @@ -4023,7 +5755,7 @@ Horizontal ruler -- eats additional dashes on the same line !! end !! test -Horizontal ruler -- does not collaps dashes on consecutive lines +Horizontal ruler -- does not collapse dashes on consecutive lines !! input ---- ---- @@ -4061,10 +5793,14 @@ Common list * item 2 *item 3 !! result -<ul><li>Common list -</li><li> item 2 -</li><li>item 3 -</li></ul> +<ul> +<li>Common list +</li> +<li> item 2 +</li> +<li>item 3 +</li> +</ul> !! end @@ -4075,10 +5811,14 @@ Numbered list #item 2 # item 3 !! result -<ol><li>Numbered list -</li><li>item 2 -</li><li> item 3 -</li></ol> +<ol> +<li>Numbered list +</li> +<li>item 2 +</li> +<li> item 3 +</li> +</ol> !! end @@ -4101,35 +5841,67 @@ Mixed list *** Level 3 #** Level 3, but ordered !! result -<ul><li>Mixed list -<ol><li> with numbers -</li></ol> -<ul><li> and bullets -</li></ul> -<ol><li> and numbers -</li></ol> -</li><li>bullets again -<ul><li>bullet level 2 -<ul><li>bullet level 3 -<ol><li>Number on level 4 -</li></ol> -</li></ul> -</li><li>bullet level 2 -<ol><li>Number on level 3 -</li><li>Number on level 3 -</li></ol> -</li></ul> -<ol><li>number level 2 -</li></ol> -</li><li>Level 1 -<ul><li><ul><li> Level 3 -</li></ul> -</li></ul> -</li></ul> -<ol><li><ul><li><ul><li> Level 3, but ordered -</li></ul> -</li></ul> -</li></ol> +<ul> +<li>Mixed list +<ol> +<li> with numbers +</li> +</ol> +<ul> +<li> and bullets +</li> +</ul> +<ol> +<li> and numbers +</li> +</ol> +</li> +<li>bullets again +<ul> +<li>bullet level 2 +<ul> +<li>bullet level 3 +<ol> +<li>Number on level 4 +</li> +</ol> +</li> +</ul> +</li> +<li>bullet level 2 +<ol> +<li>Number on level 3 +</li> +<li>Number on level 3 +</li> +</ol> +</li> +</ul> +<ol> +<li>number level 2 +</li> +</ol> +</li> +<li>Level 1 +<ul> +<li><ul> +<li> Level 3 +</li> +</ul> +</li> +</ul> +</li> +</ul> +<ol> +<li><ul> +<li><ul> +<li> Level 3, but ordered +</li> +</ul> +</li> +</ul> +</li> +</ol> !! end @@ -4139,10 +5911,14 @@ Nested lists 1 *foo **bar !! result -<ul><li>foo -<ul><li>bar -</li></ul> -</li></ul> +<ul> +<li>foo +<ul> +<li>bar +</li> +</ul> +</li> +</ul> !! end @@ -4152,10 +5928,15 @@ Nested lists 2 **foo *bar !! result -<ul><li><ul><li>foo -</li></ul> -</li><li>bar -</li></ul> +<ul> +<li><ul> +<li>foo +</li> +</ul> +</li> +<li>bar +</li> +</ul> !! end @@ -4165,10 +5946,14 @@ Nested lists 3 (first element empty) * **bar !! result -<ul><li> -<ul><li>bar -</li></ul> -</li></ul> +<ul> +<li> +<ul> +<li>bar +</li> +</ul> +</li> +</ul> !! end @@ -4178,10 +5963,15 @@ Nested lists 4 (first element empty) ** *bar !! result -<ul><li><ul><li> -</li></ul> -</li><li>bar -</li></ul> +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li>bar +</li> +</ul> !! end @@ -4191,10 +5981,15 @@ Nested lists 5 (both elements empty) ** * !! result -<ul><li><ul><li> -</li></ul> -</li><li> -</li></ul> +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li> +</li> +</ul> !! end @@ -4204,10 +5999,14 @@ Nested lists 6 (both elements empty) * ** !! result -<ul><li> -<ul><li> -</li></ul> -</li></ul> +<ul> +<li> +<ul> +<li> +</li> +</ul> +</li> +</ul> !! end @@ -4216,10 +6015,16 @@ Nested lists 7 (skip initial nesting levels) !! input *** foo !! result -<ul><li><ul><li><ul><li> foo -</li></ul> -</li></ul> -</li></ul> +<ul> +<li><ul> +<li><ul> +<li> foo +</li> +</ul> +</li> +</ul> +</li> +</ul> !! end @@ -4231,13 +6036,21 @@ Nested lists 8 (multiple nesting transitions) ** baz * boo !! result -<ul><li> foo -<ul><li><ul><li> bar -</li></ul> -</li><li> baz -</li></ul> -</li><li> boo -</li></ul> +<ul> +<li> foo +<ul> +<li><ul> +<li> bar +</li> +</ul> +</li> +<li> baz +</li> +</ul> +</li> +<li> boo +</li> +</ul> !! end @@ -4248,10 +6061,14 @@ Nested lists 8 (multiple nesting transitions) *<!--cmt-->bar <!--cmt-->*baz !! result -<ul><li>foo -</li><li>bar -</li><li>baz -</li></ul> +<ul> +<li>foo +</li> +<li>bar +</li> +<li>baz +</li> +</ul> !! end @@ -4261,34 +6078,268 @@ Nested lists 8 (multiple nesting transitions) *foo {{echo|bar }}*baz !! result -<ul><li>foo bar -</li><li>baz -</li></ul> +<ul> +<li>foo bar +</li> +<li>baz +</li> +</ul> + +!! end + +!! test +List items are not parsed correctly following a <pre> block (bug 785) +!! input +* <pre>foo</pre> +* <pre>bar</pre> +* zar +!! result +<ul> +<li> <pre>foo</pre> +</li> +<li> <pre>bar</pre> +</li> +<li> zar +</li> +</ul> + +!! 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 +<ul> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> +<ul> +<li> item 0 +</li> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> +<ul> +<li> item 0 +</li> +<li> notSOL +</li> +<li> item 1 +</li> +<li> item 2 +</li> +</ul> + +!! end + +!! test +List interrupted by empty line or heading +!! input +* foo + +** bar +== A heading == +* Another list item +!! result +<ul> +<li> foo +</li> +</ul> +<ul> +<li><ul> +<li> bar +</li> +</ul> +</li> +</ul> +<h2><span class="mw-headline" id="A_heading">A heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: A heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<ul> +<li> Another list item +</li> +</ul> + +!!end + +!!test +Multiple list tags generated by templates +!!input +{{echo|<li>}}a +{{echo|<li>}}b +{{echo|<li>}}c +!!result +<li>a +<li>b +<li>c</li> +</li> +</li> + +!!end + +!!test +Single-comment whitespace lines dont break lists, and neither do multi-comment whitespace lines +!!input +*a +<!--This line will NOT split the list--> +*b + <!--This line will NOT split the list either--> +*c + <!--foo--> <!----> <!--This line NOT split the list either--> +*d +!!result +<ul> +<li>a +</li> +<li>b +</li> +<li>c +</li> +<li>d +</li> +</ul> + +!!end + +!!test +Replacing whitespace with tabs still doesn't break the list (gerrit 78327) +!!input +*a +<!--This line will NOT split the list--> +*b + <!--This line will NOT split the list either--> +*c + <!--foo--> <!----> <!--This line NOT split the list + either--> +*d +!!result +<ul> +<li>a +</li> +<li>b +</li> +<li>c +</li> +<li>d +</li> +</ul> +!!end + +!!test +Test the li-hack +(Cannot test this with PHP parser since it relies on Tidy for the hack) +!!options +parsoid=wt2html,wt2wt +!!input +* foo +* <li>li-hack +* {{echo|<li>templated li-hack}} +* <!--foo--> <li> unsupported li-hack with preceding comments + +<ul> +<li><li>not a li-hack +</li> +</ul> +!!result +<ul> +<li> foo</li> +<li>li-hack</li> +<li about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<li>templated li-hack"}}}}]}'>templated li-hack</li> +<li> <!--foo--> </li> +<li> li-hack with preceding comments</li> +</ul> + +<ul> +<li></li> +<li>not a li-hack +</li> +</ul> +!!end + +!! test +Parsoid: Make sure nested lists are serialized on their own line even if HTML contains no newlines +!! options +parsoid +!! input +# foo +## bar +* foo +** bar +: foo +:: bar +!! result +<ol> +<li> foo<ol> +<li> bar</li> +</ol></li> +</ol><ul> +<li> foo<ul> +<li> bar</li> +</ul></li> +</ul><dl> +<dd> foo<dl> +<dd> bar</dd> +</dl></dd> +</dl> !! end !! test +Parsoid: Test of whitespace serialization with Templated bullets +!! options +parsoid +!! input +* {{bullet}} +!! result +<ul> +<li> </li><li about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"bullet","href":"./Template:Bullet"},"params":{},"i":0}}]}'> Bar</li> +</ul> +!! end + +# ------------------------------------------------------------------------ +# The next set of tests are about Parsoid's ability to handle badly nested +# tags (parse, minimize scope of fixup, and roundtrip back) +# ------------------------------------------------------------------------ + +!! test Unbalanced closing block tags break a list -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input <div> *a</div><div> *b</div> !! result <div> -<ul><li>a -</li></ul></div><div> -<ul><li>b -</li></ul></div> +<ul> +<li>a +</li> +</ul></div><div> +<ul> +<li>b +</li> +</ul></div> !! end !! test Unbalanced closing non-block tags don't break a list -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input <span> *a</span><span> @@ -4296,23 +6347,29 @@ disabled !! result <p><span></span> </p> -<ul><li>a<span></span> -</li><li>b -</li></ul> +<ul> +<li>a<span></span> +</li> +<li>b +</li> +</ul> !! end !! test Unclosed formatting tags that straddle lists are closed and reopened -(Disabled since php parser generates broken html -- relies on Tidy to fix up) +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) !! options -disabled +parsoid !! input # <s> a # b </s> !! result -<ol><li> <s> a </s> -</li><li> <s> b </s> -</li></ol> +<ol> +<li> <s> a </s> +</li> +<li> <s> b </s> +</li> +</ol> !! end !!test @@ -4335,88 +6392,31 @@ parsoid !!end !! test -List items are not parsed correctly following a <pre> block (bug 785) -!! input -* <pre>foo</pre> -* <pre>bar</pre> -* zar -!! result -<ul><li> <pre>foo</pre> -</li><li> <pre>bar</pre> -</li><li> zar -</li></ul> - -!! end - -!! test -List items from template +Table with missing opening <tr> tag +!! options +parsoid=wt2html,wt2wt !! input - -{{inner list}} -* item 2 - -* item 0 -{{inner list}} -* item 2 - -* item 0 -* notSOL{{inner list}} -* item 2 +<table> +<td>foo</td> +</tr> +</table> !! result -<ul><li> item 1 -</li><li> item 2 -</li></ul> -<ul><li> item 0 -</li><li> item 1 -</li><li> item 2 -</li></ul> -<ul><li> item 0 -</li><li> notSOL -</li><li> item 1 -</li><li> item 2 -</li></ul> - +<table> +<tr> +<td>foo</td> +</tr> +</table> !! end -!! test -List interrupted by empty line or heading -!! input -* foo - -** bar -== A heading == -* Another list item -!! result -<ul><li> foo -</li></ul> -<ul><li><ul><li> bar -</li></ul> -</li></ul> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: A heading">edit</a>]</span> <span class="mw-headline" id="A_heading"> A heading </span></h2> -<ul><li> Another list item -</li></ul> - -!!end - -!!test -Multiple list tags generated by templates -!!input -{{echo|<li>}}a -{{echo|<li>}}b -{{echo|<li>}}c -!!result -<li>a -<li>b -<li>c</li> -</li> -</li> - -!!end - ### ### Magic Words ### +# Note that the current date is hard-coded as +# 1970-01-01T00:02:03Z (a Thursday) +# when running parser tests. The timezone is also fixed to GMT, so +# local date will be identical to current date. + !! test Magic Word: {{CURRENTDAY}} !! input @@ -4463,6 +6463,15 @@ Magic Word: {{CURRENTMONTH}} !! end !! test +Magic Word: {{CURRENTMONTH1}} +!! input +{{CURRENTMONTH1}} +!! result +<p>1 +</p> +!! end + +!! test Magic Word: {{CURRENTMONTHABBREV}} !! input {{CURRENTMONTHABBREV}} @@ -4499,6 +6508,15 @@ Magic Word: {{CURRENTTIME}} !! end !! test +Magic Word: {{CURRENTHOUR}} +!! input +{{CURRENTHOUR}} +!! result +<p>00 +</p> +!! end + +!! test Magic Word: {{CURRENTWEEK}} (@bug 4594) !! input {{CURRENTWEEK}} @@ -4517,6 +6535,66 @@ Magic Word: {{CURRENTYEAR}} !! end !! test +Magic Word: {{CURRENTTIMESTAMP}} +!! input +{{CURRENTTIMESTAMP}} +!! result +<p>19700101000203 +</p> +!! end + +!! test +Magic Words LOCAL (UTC) +!! input +* {{LOCALMONTH}} +* {{LOCALMONTH1}} +* {{LOCALMONTHNAME}} +* {{LOCALMONTHNAMEGEN}} +* {{LOCALMONTHABBREV}} +* {{LOCALDAY}} +* {{LOCALDAY2}} +* {{LOCALDAYNAME}} +* {{LOCALYEAR}} +* {{LOCALTIME}} +* {{LOCALHOUR}} +* {{LOCALWEEK}} +* {{LOCALDOW}} +* {{LOCALTIMESTAMP}} +!! result +<ul> +<li> 01 +</li> +<li> 1 +</li> +<li> January +</li> +<li> January +</li> +<li> Jan +</li> +<li> 1 +</li> +<li> 01 +</li> +<li> Thursday +</li> +<li> 1970 +</li> +<li> 00:02 +</li> +<li> 00 +</li> +<li> 1 +</li> +<li> 4 +</li> +<li> 19700101000203 +</li> +</ul> + +!! end + +!! test Magic Word: {{FULLPAGENAME}} !! options title=[[User:Ævar Arnfjörð Bjarmason]] @@ -4539,6 +6617,93 @@ title=[[User:Ævar Arnfjörð Bjarmason]] !! end !! test +Magic Word: {{TALKSPACE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACE}} +!! result +<p>User talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACE}}, same namespace +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACE}} +!! result +<p>User talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACE}}, main namespace +!! options +title=[[Parser Test]] +!! input +{{TALKSPACE}} +!! result +<p>Talk +</p> +!! end + +!! test +Magic Word: {{TALKSPACEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKSPACEE}} +!! result +<p>User_talk +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}}, same namespace +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{SUBJECTSPACE}}, main namespace +!! options +title=[[Parser Test]] +!! input +{{SUBJECTSPACE}} +!! result + +!! end + +!! test +Magic Word: {{SUBJECTSPACEE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTSPACEE}} +!! result +<p>User +</p> +!! end + +!! test Magic Word: {{NAMESPACE}} !! options title=[[User:Ævar Arnfjörð Bjarmason]] @@ -4572,11 +6737,121 @@ title=[[User:Ævar Arnfjörð Bjarmason]] !! end !! test +Magic Word: {{SUBPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage +!! input +{{SUBPAGENAME}} +!! result +<p>sub ö +</p> +!! end + +!! test +Magic Word: {{SUBPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub ö]] subpage +!! input +{{SUBPAGENAMEE}} +!! result +<p>sub_%C3%B6 +</p> +!! end + +!! test +Magic Word: {{ROOTPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage +!! input +{{ROOTPAGENAME}} +!! result +<p>Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{ROOTPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub/sub2]] subpage +!! input +{{ROOTPAGENAMEE}} +!! result +<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{BASEPAGENAME}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub]] subpage +!! input +{{BASEPAGENAME}} +!! result +<p>Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{BASEPAGENAMEE}} +!! options +title=[[Ævar Arnfjörð Bjarmason/sub]] subpage +!! input +{{BASEPAGENAMEE}} +!! result +<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{TALKPAGENAME}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKPAGENAME}} +!! result +<p>User talk:Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{TALKPAGENAMEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{TALKPAGENAMEE}} +!! result +<p>User_talk:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{SUBJECTPAGENAME}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTPAGENAME}} +!! result +<p>User:Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{SUBJECTPAGENAMEE}} +!! options +title=[[User talk:Ævar Arnfjörð Bjarmason]] +!! input +{{SUBJECTPAGENAMEE}} +!! result +<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test Magic Word: {{NUMBEROFFILES}} !! input {{NUMBEROFFILES}} !! result -<p>2 +<p>4 </p> !! end @@ -4654,6 +6929,15 @@ Magic Word: {{SCRIPTPATH}} !! end !! test +Magic Word: {{STYLEPATH}} +!! input +{{STYLEPATH}} +!! result +<p>/skins +</p> +!! end + +!! test Magic Word: {{SERVER}} !! input {{SERVER}} @@ -4681,6 +6965,36 @@ Magic Word: {{SITENAME}} !! end !! test +Case-sensitive magic words, when cased differently, should just be template transclusions +!! input +{{CurrentMonth}} +{{currentday}} +{{cURreNTweEK}} +{{currentHour}} +!! result +<p><a href="/index.php?title=Template:CurrentMonth&action=edit&redlink=1" class="new" title="Template:CurrentMonth (page does not exist)">Template:CurrentMonth</a> +<a href="/index.php?title=Template:Currentday&action=edit&redlink=1" class="new" title="Template:Currentday (page does not exist)">Template:Currentday</a> +<a href="/index.php?title=Template:CURreNTweEK&action=edit&redlink=1" class="new" title="Template:CURreNTweEK (page does not exist)">Template:CURreNTweEK</a> +<a href="/index.php?title=Template:CurrentHour&action=edit&redlink=1" class="new" title="Template:CurrentHour (page does not exist)">Template:CurrentHour</a> +</p> +!! end + +!! test +Case-insensitive magic words should still work with weird casing. +!! input +{{sErVeRNaMe}} +{{LCFirst:AOEU}} +{{ucFIRST:aoeu}} +{{SERver}} +!! result +<p>example.org +aOEU +Aoeu +<a rel="nofollow" class="external free" href="http://example.org">http://example.org</a> +</p> +!! end + +!! test Namespace 1 {{ns:1}} !! input {{ns:1}} @@ -5422,8 +7736,8 @@ Bug 6563: Edit link generation for section shown by <includeonly> !! input {{includeonly section}} !! result -<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Includeonly_section">Includeonly section</span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Section_T-1">Section T-1</span></h2> +<h2><span class="mw-headline" id="Includeonly_section">Includeonly section</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_T-1">Section T-1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -5449,7 +7763,7 @@ Bug 6563: Edit link generation for section suppressed by <includeonly> </includeonly> ==Section 1== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2> +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -5473,6 +7787,77 @@ Un-closed <includeonly> !! result !! end +# TODO: test with DOM fragment reuse! +!! test +Parsoid: DOM fragment reuse +!! options +parsoid=wt2wt,wt2html +!! input +a{{echo|b<table></table>c}}d + +a{{echo|b +<table></table> +c}}d + +{{echo|a + +<table></table> + +b}} +!! result +a<span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b +<table></table>c"}},"i":0}}]}'>b</span> +<table about="#mwt1"></table><span about="#mwt1">c</span>d + + +<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["a",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b\n<table></table>\nc"}},"i":0}},"d"]}'>ab</p><span about="#mwt2"> +</span> +<table about="#mwt2"></table><span about="#mwt2"> +</span> +<p about="#mwt2">cd</p> + + +<p about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n\n<table></table>\n\nb"}},"i":0}}]}'>a</p><span about="#mwt3"> + +</span> +<table about="#mwt3"></table><span about="#mwt3"> + +</span> +<p about="#mwt3">b</p> +!! end + +!! test +Parsoid: Merge double tds (bug 50603) +!! options +parsoid +!! input +{| +|{{echo|{{!}} foo}} +|} +!! result +<table><tbody> +<tr><td about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":0}}]}'> foo</td></tr> +</tbody></table> +!! end + +!! test +Parsoid: Merge double tds in nested transclusion content (bug 50603) +!! options +parsoid +!! input +{{echo|<div>}} +{| +|{{echo|{{!}} foo}} +|} +{{echo|</div>}} +!! result +<div about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<div>"}},"i":0}},"\n{|\n|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"{{!}} foo"}},"i":1}},"\n|}\n",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"</div>"}},"i":2}}]}'> +<table><tbody> +<tr><td data-mw='{"parts":["|"]}'> foo</td></tr> +</tbody></table> +</div> +!! end + ### ### <includeonly> and <noinclude> in attributes ### @@ -5569,8 +7954,10 @@ Templates: 1. Simple use Templates: 2. Inside a block tag !!input <div>{{echo|Foo}}</div> +<blockquote>{{echo|Foo}}</blockquote> !!result <div>Foo</div> +<blockquote>Foo</blockquote> !!end @@ -5612,6 +7999,19 @@ bar <div>baz</div> !!end !!test +Templates: P-wrapping: 1d. Template preceded by comment-only line +!!options +parsoid +!!input +<!-- foo --> +{{echo|Bar}} +!!result +<!-- foo --> + +<p about="#mwt223" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"Bar"}},"i":0}}]}'>Bar</p> +!!end + +!!test Templates: Inline Text: 1. Multiple tmeplate uses !!input {{echo|Foo}}bar{{echo|baz}} @@ -5771,6 +8171,15 @@ Templates: HTML Tag: 6. Generation of end piece of HTML attr value !!end !!test +Templates: HTML Tag: 7. Generation of partial attribute key string +!!input +<div st{{echo|yle}}="color:red;">foo</div> +!!result +<div style="color:red;">foo</div> + +!!end + +!!test Templates: HTML Tables: 1. Generating start of a HTML table !!input {{echo|<table><tr><td>foo</td>}}</tr></table> @@ -5861,6 +8270,20 @@ Templates: HTML Tables: 4f. Generating a single tag of a HTML table !!end !!test +Templates: HTML Tables: 5. Proper fostering of categories from inside +!!options +parsoid=wt2html,wt2wt +!!input +<table>[[Category:foo1]]<tr><td>foo</td></tr></table> +<!--Two categories (Bug 50330)--> +<table>[[Category:bar1]][[Category:bar2]]<tr><td>foo</td></tr></table> +!!result +<link rel="mw:WikiLink/Category" href="./Category:Foo1"><table><tbody><tr><td>foo</td></tr></tbody></table> +<!--Two categories (Bug 50330)--> +<link rel="mw:WikiLink/Category" href="./Category:Bar1"><link rel="mw:WikiLink/Category" href="./Category:Bar2"><table><tbody><tr><td>foo</td></tr></tbody></table> +!!end + +!!test Templates: Wiki Tables: 1a. Fostering of entire template content !!input {| @@ -5967,9 +8390,12 @@ unused}}}} *{{echo|b {{nonexistent| unused}}}} !!result -<ul><li>a <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> -</li><li>b <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> -</li></ul> +<ul> +<li>a <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> +</li> +<li>b <a href="/index.php?title=Template:Nonexistent&action=edit&redlink=1" class="new" title="Template:Nonexistent (page does not exist)">Template:Nonexistent</a> +</li> +</ul> !!end @@ -5986,24 +8412,24 @@ Templates: Ugly nesting: 1. Quotes opened/closed across templates (echo) Templates: Ugly nesting: 2. Quotes opened/closed across templates (echo_with_span) (PHP parser generates misnested html) !! options -disabled +parsoid !!input {{echo_with_span|''a}}{{echo_with_span|b''c''d}}{{echo_with_span|''e}} !!result -<p><span><i>a</i></span><i><span>b</span></i><span>c</span><i>d</i><span>e</span></p> +<p><span about="#mwt1" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"''a"}},"i":0}}]}"><i>a</i></span><i about="#mwt2" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"b''c''d"}},"i":0}},{"template":{"target":{"wt":"echo_with_span","href":"./Template:Echo_with_span"},"params":{"1":{"wt":"''e"}},"i":1}}]}"><span>b</span></i><span about="#mwt2">c</span><i about="#mwt2">d<span></span></i><span about="#mwt2">e</span></p> !!end !!test Templates: Ugly nesting: 3. Quotes opened/closed across templates (echo_with_div) -(PHP parser generates misnested html) +(PHP parser generates misnested html; Parsoid html2wt mode adds newlines between {{echo}}s) !! options -disabled +parsoid=wt2html,wt2wt !!input {{echo_with_div|''a}}{{echo_with_div|b''c''d}}{{echo_with_div|''e}} !!result -<div><i>a</i></div> -<div><i>b</i>c<i>d</i></div> -<div>e</div> +<div about="#mwt1" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"''a"}},"i":0}}]}"><i>a</i></div> +<div about="#mwt2" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"b''c''d"}},"i":0}}]}"><i>b</i>c<i>d</i></div> +<div about="#mwt3" typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo_with_div","href":"./Template:Echo_with_div"},"params":{"1":{"wt":"''e"}},"i":0}}]}">e</div> !!end !!test @@ -6026,9 +8452,12 @@ parsoid |bar |} !!result -<table about="#mwt1" typeof="mw:Object/Template "> -<tbody><tr><td>foo</td></tr></tbody></table><span about="#mwt1"> -bar</span><span about="#mwt1"> +<table about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["{|\n|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</table>"}},"i":0}},"\n|bar\n|}"]}'> + +<tbody> +<tr> +<td>foo</td></tr></tbody></table><span about="#mwt1"> +</span><span about="#mwt1">bar</span><span about="#mwt1"> </span> !!end @@ -6058,24 +8487,24 @@ parsoid </tr> </table> !!result -<table about="#mwt1" typeof="mw:Object/Template"> - <tbody><tr > - <td > - <table > - <tbody><tr > - <td >1. foo </td></tr></tbody></table></td> - <td > bar </td> - <td >2. baz </td></tr></tbody></table><span about="#mwt1"> - </span><span about="#mwt1"> - - abc</span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - </span><span about="#mwt1"> - - xyz</span><span about="#mwt1"> - </span><span about="#mwt1"> +<table about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":["<table>\n <tr>\n <td>\n <table>\n <tr>\n <td>1. ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo </table>"}},"i":0}},"</td>\n <td> bar </td>\n <td>2. ",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"baz </table>"}},"i":1}},"</td>\n </tr>\n <tr>\n <td>abc</td>\n </tr>\n </table>\n </td>\n </tr>\n <tr>\n <td>xyz</td>\n </tr>\n</table>"]}'> + <tbody><tr> + <td> + <table> + <tbody><tr> + <td>1. foo </td></tr></tbody></table></td> + <td> bar </td> + <td>2. baz </td></tr></tbody></table><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2">abc</span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2"> + </span><span about="#mwt2">xyz</span><span about="#mwt2"> + </span><span about="#mwt2"> </span> !!end @@ -6237,10 +8666,13 @@ wiki<nowiki>nowiki<!--nowiki</nowiki>wiki wiki<nowiki>nowiki<!--nowiki</nowiki>wiki !!end +# Leading @ in this template definition works around a limitation +# in parsoid's parserTests which otherwise strips the <span> from the +# result (confusing it for a template wrapper) !! article Template:dangerous !!text -<span onmouseover="alert('crap')">Oh no</span> +@<span onmouseover="alert('crap')">Oh no</span> !!endarticle !!test @@ -6248,7 +8680,7 @@ Template:dangerous !! input {{Template:dangerous}} !! result -<p><span>Oh no</span> +<p>@<span>Oh no</span> </p> !! end @@ -6637,6 +9069,62 @@ But not inside includeonly <includeonly>{{subst:Foo}}</includeonly> !! end +!! test +Parsoid: Recognize nowiki with trailing space in tags +!! options +parsoid=wt2html +!! input +<nowiki ><div>[[foo]]</nowiki > + +a<nowiki / >b + +c<nowiki />d + +e<nowiki/ >f +!! result +<p><span typeof="mw:Nowiki"><div>[[foo]]</span></p> +<p>ab</p> +<p>cd</p> +<p>ef</p> +!! end + +!! test +Parsoid: Recognize nowiki with odd capitalization +!! options +parsoid=wt2html +!! input +<noWikI ><div>[[foo]]</Nowiki > +!! result +<p><span typeof="mw:Nowiki"><div>[[foo]]</span></p> +!! end + + +!! test +Parsoid: Escape nowiki with trailing space in tags +!! options +parsoid=html2wt +!! input +<nowiki > foo </nowiki > + +a<nowiki />b + +c<nowiki/ >d +!! result +<p><nowiki > foo </nowiki ></p> +<p>a<nowiki />b</p> +<p>c<nowiki/ >d</p> +!! end + +!! test +Parsoid: Escape weird noWikI capitalizations +!! options +parsoid=html2wt +!! input +<noWikI > foo </NoWikI > +!! result +<p><noWikI > foo </NoWikI ></p> +!! end + ### ### Message transform tests ### @@ -6705,9 +9193,9 @@ Special:RecentChanges/param !! options msg !! input -{{#special:foobarnonexistent}} +{{#special:foobar nonexistent}} !! result -No such special page +Special:Foobar nonexistent !! end !! test @@ -6735,16 +9223,21 @@ Special:RecentChanges/param !! options msg !! input -{{#speciale:foobarnonexistent}} +{{#speciale:foobar nonexistent}} !! result -No_such_special_page +Special:Foobar_nonexistent !! end ### ### Images ### +### For Parsoid-specific tests, see +#### http://www.mediawiki.org/wiki/Parsoid/MediaWiki_DOM_spec#Images + !! test -Simple image +Simple image (php) +!! options +php !! input [[Image:foobar.jpg]] !! result @@ -6753,16 +9246,20 @@ Simple image !! end !! test -Right-aligned image +Simple image (parsoid) +!! options +parsoid=wt2html !! input -[[Image:foobar.jpg|right]] +[[Image:foobar.jpg]] !! result -<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> - +<p><span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span> +</p> !! end !! test -Simple image (using File: namespace, now canonical) +Simple image (using File: namespace, now canonical) (php) +!! options +php !! input [[File:foobar.jpg]] !! result @@ -6771,29 +9268,108 @@ Simple image (using File: namespace, now canonical) !! end !! test -Image with caption +Simple image (using File: namespace, now canonical) (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|right|Caption text]] +[[File:Foobar.jpg]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span> +</p> +!! end + +!! test +Right-aligned image (php) +!! options +php +!! input +[[Image:foobar.jpg|right]] +!! result +<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> + +!! end + +!! test +Right-aligned image (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure> +!! end + +!! test +Image with caption (php) +!! options +php +!! input +[[File:Foobar.jpg|right|Caption text]] +!! result +<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> + +!! end + +!! test +Image with caption (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right|Caption text]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with empty attribute (php) +!! options +php +!! input +[[File:Foobar.jpg|right||Caption text]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with empty attribute +Image with empty attribute (parsoid) +!! options +parsoid=wt2html +!! input +[[File:Foobar.jpg|right||Caption text]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with attributes from template (php) +!! options +php !! input -[[Image:foobar.jpg|right||Caption text]] +[[File:Foobar.jpg|{{image_attribs}}]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with link tails +Image with attributes from template (parsoid) +!! options +parsoid !! input -123[[Image:foobar.jpg]]456 -123[[Image:foobar.jpg|right]]456 -123[[Image:foobar.jpg|thumb]]456 +[[File:Foobar.jpg|{{image_attribs}}]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure> +!! end + +!! test +Image with link tails (php) +!! options +php +!! input +123[[File:Foobar.jpg]]456 +123[[File:Foobar.jpg|right]]456 +123[[File:Foobar.jpg|thumb]]456 !! result <p>123<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>456 </p> @@ -6803,20 +9379,48 @@ Image with link tails !! end !! test -Image with multiple captions -- only last one is accepted +Image with link tails (parsoid) +!! options +parsoid +!! input +123[[File:Foobar.jpg]]456 +123[[File:Foobar.jpg|right]]456 +123[[File:Foobar.jpg|thumb]]456 +!! result +<p>123<span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span>456</p> +123<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure>456 +123<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="20" width="180"></a></figure>456 +!! end + +!! test +Image with multiple captions -- only last one is accepted (php) +!! options +php !! input -[[Image:foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] +[[File:Foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption3 - accepted"><img alt="Caption3 - accepted" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> !! end !! test -Image with width attribute at different positions +Image with multiple captions -- only last one is accepted (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|right|Caption1 - ignored|[[Caption2]] - ignored|Caption3 - accepted]] +!! result +<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption3 - accepted</figcaption></figure> +!! end + +!! test +Image with width attribute at different positions (php) +!! options +php !! input -[[Image:foobar.jpg|200px|right|Caption]] -[[Image:foobar.jpg|right|200px|Caption]] -[[Image:foobar.jpg|right|Caption|200px]] +[[File:Foobar.jpg|200px|right|Caption]] +[[File:Foobar.jpg|right|200px|Caption]] +[[File:Foobar.jpg|right|Caption|200px]] !! result <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div> <div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption"><img alt="Caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a></div> @@ -6825,23 +9429,84 @@ Image with width attribute at different positions !! end !! test -Image with link parameter, wiki target +Image with width attribute at different positions (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|200px|right|Caption]] +[[File:Foobar.jpg|right|200px|Caption]] +[[File:Foobar.jpg|right|Caption|200px]] +!! result +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +<figure class="mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" height="23" width="200"></a><figcaption>Caption</figcaption></figure> +!! end + +!! test +Image with link parameter, wiki target (php) +!! options +php !! input -[[Image:foobar.jpg|link=Target page]] +[[File:Foobar.jpg|link=Main Page]] !! result -<p><a href="/wiki/Target_page" title="Target page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +<p><a href="/wiki/Main_Page" title="Main Page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test -Image with link parameter, URL target +Image with link parameter, wiki target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=Main Page]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter, URL target (php) +!! options +php !! input -[[Image:foobar.jpg|link=http://example.com/]] +[[File:Foobar.jpg|link=http://example.com/]] !! result <p><a href="http://example.com/" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end +# parsoid bug 49293 (part 1) +!! test +Image with link parameter, URL target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=http://example.com/]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter, protocol-less URL target (php) +!! options +php +!! input +[[File:Foobar.jpg|link=//example.com/]] +!! result +<p><a href="//example.com/" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +# parsoid bug 49293 (part 2) +!! test +Image with link parameter, protocol-less URL target (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=//example.com/]] +!! result +<p><span class="mw-default-size" typeof="mw:Image"><a href="//example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + !! test Image with link parameter, wgExternalLinkTarget !! input @@ -6887,34 +9552,72 @@ wgExternalLinkTarget='foobar' !! end !! test -Image with empty link parameter +Image with empty link parameter (php) +!! options +php !! input -[[Image:foobar.jpg|link=]] +[[File:Foobar.jpg|link=]] !! result <p><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /> </p> !! end !! test -Image with link parameter (wiki target) and unnamed parameter +Image with empty link parameter (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|link=Target page|Title]] +[[File:Foobar.jpg|link=]] !! result -<p><a href="/wiki/Target_page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +<p><span class="mw-default-size" typeof="mw:Image"><span><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></span></span></p> +!! end + +!! test +Image with link parameter (wiki target) and unnamed parameter (php) +!! options +php +!! input +[[File:Foobar.jpg|link=Main Page|Title]] +!! result +<p><a href="/wiki/Main_Page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test -Image with link parameter (URL target) and unnamed parameter +Image with link parameter (wiki target) and unnamed parameter (parsoid) +!! options +parsoid !! input -[[Image:foobar.jpg|link=http://example.com/|Title]] +[[File:Foobar.jpg|link=Main Page|Title]] +!! result +<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test +Image with link parameter (URL target) and unnamed parameter (php) +!! options +php +!! input +[[File:Foobar.jpg|link=http://example.com/|Title]] !! result <p><a href="http://example.com/" title="Title" rel="nofollow"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </p> !! end !! test +Image with link parameter (URL target) and unnamed parameter (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=http://example.com/|Title]] +!! result +<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="http://example.com/"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span></p> +!! end + +!! test Thumbnail image with link parameter +!! options +php !! input [[Image:foobar.jpg|thumb|link=http://example.com/|Title]] !! result @@ -6923,6 +9626,61 @@ Thumbnail image with link parameter !! end !! test +Manually-specified thumbnail image +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/File:Foobar.jpg"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link to wiki page +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=Main Page|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link to url +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=http://example.com|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="http://example.com"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit no link +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test +Manually-specified thumbnail image with explicit link and alt text +!! options +php +!! input +[[Image:Foobar.jpg|thumb=Thumb.png|link=Main Page|alt=alttext|Title]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="alttext" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div> + +!! end + +!! test Image with frame and link !! input [[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]]] @@ -7006,6 +9764,36 @@ Thumbnail image caption with a free URL and explicit alt !! end !! test +SVG thumbnails with no language set +!! options +!! input +[[File:Foobar.svg|thumb|width=200]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>width=200</div></div></div> + +!! end + +!! test +SVG thumbnails with language de +!! options +!! input +[[File:Foobar.svg|thumb|width=200|lang=de]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=File:Foobar.svg&lang=de" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/langde-180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/langde-270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/langde-360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>width=200</div></div></div> + +!! end + +!! test +SVG thumbnails with invalid language code +!! options +!! input +[[File:Foobar.svg|thumb|width=200|lang=invalid.language.code]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.svg" class="image"><img alt="" src="http://example.com/images/thumb/f/ff/Foobar.svg/180px-Foobar.svg.png" width="180" height="180" class="thumbimage" srcset="http://example.com/images/thumb/f/ff/Foobar.svg/270px-Foobar.svg.png 1.5x, http://example.com/images/thumb/f/ff/Foobar.svg/360px-Foobar.svg.png 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.svg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>lang=invalid.language.code</div></div></div> + +!! end + +!! test BUG 1887: A ISBN with a thumbnail !! input [[Image:foobar.jpg|thumb|ISBN 1235467890]] @@ -7200,6 +9988,152 @@ wgEnableUploads=0 </p> !! end +# Parsoid-specific testing for images +# http://www.mediawiki.org/wiki/Parsoid/MediaWiki_DOM_spec#Images +# Currently imperfect due to a flaw in the Parsoid testrunner +# Work in progress +# THESE TESTS SHOULD BE MOVED UP and merged with the php-specific +# image tests. + +!! test +Parsoid-specific image handling - simple image with size and middle alignment +!! options +parsoid +!! input +[[Image:Foobar.jpg|50px|middle]] +!! result +<p> +<span class="mw-valign-middle" typeof="mw:Image"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - simple image with both sizes, a baseline alignment, and a caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x10px|baseline|caption]] +!! result +<p> +<span class="mw-valign-baseline" typeof="mw:Image" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/89px-Foobar.jpg" height="10" width="89"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - simple image with border and size spec +!! options +parsoid +!! input +[[Image:Foobar.jpg|50px|border|caption]] +!! result +<p> +<span class="mw-image-border" typeof="mw:Image" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50"> +</a> +</span> +</p> +!! end + +!! test +Parsoid-specific image handling - thumbnail with halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|thumb|left|baseline|caption content]] +!! result +<figure class="mw-default-size mw-halign-left mw-valign-baseline" typeof="mw:Image/Thumb"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" height="21" width="180" /> +</a> +<figcaption>caption content</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - thumbnail with specific size, halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|thumb|50x50px|right|middle|caption]] +!! result +<figure class="mw-halign-right mw-valign-middle" typeof="mw:Image/Thumb"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/50px-Foobar.jpg" height="6" width="50" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - framed image with specific size and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x50px|frame|caption]] +!! result +<figure typeof="mw:Image/Frame"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - framed image with specific size, halign, valign, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|500x50px|frame|left|baseline|caption]] +!! result +<figure class="mw-halign-left mw-valign-baseline" typeof="mw:Image/Frame"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +<figcaption>caption</figcaption> +</figure> +!! end + +!! test +Parsoid-specific image handling - frameless image with specific size, border, and caption +!! options +parsoid +!! input +[[Image:Foobar.jpg|frameless|500x50px|border|caption]] +!! result +<p> +<span class="mw-image-border" typeof="mw:Image/Frameless" data-mw="{"caption":"caption"}"> +<a href="File:Foobar.jpg"> +<img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/442px-Foobar.jpg" height="50" width="442" /> +</a> +</p> +!! end + +#!! test +#Parsoid-specific image handling - simple image with a formatted caption +#!! options +#parsoid +#!! input +#[[Image:Foobar.jpg|<table><tr><td>a</td><td>b</td></tr><tr><td>c</td></tr></table>]] +#!! result +#<p> +#<span typeof="mw:Image"> +#<a class="mw-default-size" href="Image:Foobar.jpg"> +#<img alt="Foobar.jpg" class="mw-default-size" src="http://example.com/images/3/3a/Foobar.jpg" height="220" width="1941"> +#</a> +#<span>abc</span> +#</span> +#</p> + ### ### Subpages @@ -7232,6 +10166,38 @@ subpage title=[[Subpage test]] </p> !! end +# TODO: make this PHP-parser compatible! +!! test +Relative subpage noslash link +!! options +parsoid=wt2wt,wt2html,html2html +subpage title=[[Subpage test/1/2/3/4]] +!!input +[[../../subpage/]] + +[[../../subpage]] +!! result +<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage/">subpage</a></p> +<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage">Subpage_test/1/2/subpage</a></p> +!! end + +# TODO: make this PHP-parser compatible! +!! test +Parsoid: dot-slash prefixed wikilinks +!! options +parsoid=wt2wt,wt2html,html2html +!!input +[[./foo]] + +[[././bar]] + +[[././baz/]] +!! result +<p><a rel="mw:WikiLink" href="./Foo">foo</a></p> +<p><a rel="mw:WikiLink" href="./Bar">bar</a></p> +<p><a rel="mw:WikiLink" href="./Baz/">baz/</a></p> +!! end + !! test Disabled subpages !! input @@ -7415,6 +10381,59 @@ Bar </p> !! end +!! test +Parsoid: Serialize link to category page with colon escape +!! options +parsoid +!! input + +[[:Category:Foo]] +[[:Category:Foo|Bar]] +!! result +<p> +<a rel="mw:WikiLink" href="Category:Foo">Category:Foo</a> +<a rel="mw:WikiLink" href="Category:Foo">Bar</a> +</p> +!! end + +!! test +Parsoid: Link prefix/suffixes aren't applied to category links +!! options +parsoid=wt2html,wt2wt,html2html +language=is +!! input +x[[Category:Foo]]y +!! result +<p>x<link rel="mw:WikiLink/Category" href="Category:Foo">y</p> +!! end + +!! test +Parsoid: Serialize link to file page with colon escape +!! options +parsoid +!! input + +[[:File:Foo.png]] +[[:File:Foo.png|Bar]] +!! result +<p> +<a rel="mw:WikiLink" href="File:Foo.png">File:Foo.png</a> +<a rel="mw:WikiLink" href="File:Foo.png">Bar</a> +</p> +!! end + +!! test +Parsoid: Serialize a genuine category link without colon escape +!! options +parsoid +!! input +[[Category:Foo]] +[[Category:Foo|Bar]] +!! result +<link rel="mw:WikiLink/Category" href="Category:Foo"> +<link rel="mw:WikiLink/Category" href="Category:Foo#Bar"> +!! end + ### ### Inter-language links ### @@ -7457,13 +10476,13 @@ More ===Smaller headline=== Blah blah !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2> +<h2><span class="mw-headline" id="Headline_1">Headline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>Some text </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2">Headline 2</span></h2> +<h2><span class="mw-headline" id="Headline_2">Headline 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>More </p> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a>]</span> <span class="mw-headline" id="Smaller_headline">Smaller headline</span></h3> +<h3><span class="mw-headline" id="Smaller_headline">Smaller headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a><span class="mw-editsection-bracket">]</span></span></h3> <p>Blah blah </p> !! end @@ -7480,7 +10499,7 @@ Section headings with TOC Some text ===Another headline=== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Headline_1"><span class="tocnumber">1</span> <span class="toctext">Headline 1</span></a> <ul> @@ -7501,15 +10520,16 @@ Some text </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a>]</span> <span class="mw-headline" id="Subheadline_1"> Subheadline 1 </span></h3> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level"> Skipping a level </span></h5> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level_2"> Skipping a level </span></h6> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2"> Headline 2 </span></h2> +</div> + +<h2><span class="mw-headline" id="Headline_1">Headline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Subheadline_1">Subheadline 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h5><span class="mw-headline" id="Skipping_a_level">Skipping a level</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h6><span class="mw-headline" id="Skipping_a_level_2">Skipping a level</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h2><span class="mw-headline" id="Headline_2">Headline 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>Some text </p> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a>]</span> <span class="mw-headline" id="Another_headline">Another headline</span></h3> +<h3><span class="mw-headline" id="Another_headline">Another headline</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7528,7 +10548,7 @@ Handling of sections up to level 6 and beyond ========= Level 9 Heading========= ========== Level 10 Heading========== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Level_1_Heading"><span class="tocnumber">1</span> <span class="toctext">Level 1 Heading</span></a> <ul> @@ -7556,17 +10576,18 @@ Handling of sections up to level 6 and beyond </ul> </li> </ul> -</td></tr></table> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline" id="Level_1_Heading"> Level 1 Heading</span></h1> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline" id="Level_2_Heading"> Level 2 Heading</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a>]</span> <span class="mw-headline" id="Level_3_Heading"> Level 3 Heading</span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline" id="Level_4_Heading"> Level 4 Heading</span></h4> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline" id="Level_5_Heading"> Level 5 Heading</span></h5> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline" id="Level_6_Heading"> Level 6 Heading</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span></h6> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span></h6> +</div> + +<h1><span class="mw-headline" id="Level_1_Heading">Level 1 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h2><span class="mw-headline" id="Level_2_Heading">Level 2 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Level_3_Heading">Level 3 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="Level_4_Heading">Level 4 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h5><span class="mw-headline" id="Level_5_Heading">Level 5 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h6><span class="mw-headline" id="Level_6_Heading">Level 6 Heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h6><span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a><span class="mw-editsection-bracket">]</span></span></h6> !! end @@ -7580,7 +10601,7 @@ TOC regression (bug 9764) == title 2 == === title 2.1 === !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7598,13 +10619,14 @@ TOC regression (bug 9764) </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="title_1.1.1">title 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7620,7 +10642,7 @@ wgMaxTocLevel=3 == title 2 == === title 2.1 === !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7634,13 +10656,14 @@ wgMaxTocLevel=3 </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="title_1.1.1">title 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h3><span class="mw-headline" id="title_1.2">title 1.2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_2.1">title 2.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> !! end @@ -7655,7 +10678,7 @@ wgMaxTocLevel=3 ====Section 1.1.1.1==== ==Section 2== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Section_1"><span class="tocnumber">1</span> <span class="toctext">Section 1</span></a> <ul> @@ -7664,12 +10687,13 @@ wgMaxTocLevel=3 </li> <li class="toclevel-1 tocsection-5"><a href="#Section_2"><span class="tocnumber">2</span> <span class="toctext">Section 2</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1">Section 1.1</span></h3> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span></h4> -<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span></h4> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2> +</div> + +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Section_1.1">Section 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h4><span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h4><span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h4> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7680,8 +10704,8 @@ Resolving duplicate section names == Foo bar == == Foo bar == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar_2"> Foo bar </span></h2> +<h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_bar_2">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7691,8 +10715,8 @@ Resolving duplicate section names with differing case (bug 10721) == Foo bar == == Foo Bar == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> Foo Bar </span></h2> +<h2><span class="mw-headline" id="Foo_bar">Foo bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_Bar_2">Foo Bar</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7711,10 +10735,10 @@ __NOTOC__ {{sections}} ==Section 4== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a>]</span> <span class="mw-headline" id="Section_0">Section 0</span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a>]</span> <span class="mw-headline" id="Section_4">Section 4</span></h2> +<h2><span class="mw-headline" id="Section_0">Section 0</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7725,8 +10749,8 @@ __NOEDITSECTION__ ==Section 1== ==Section 2== !! result -<h2> <span class="mw-headline" id="Section_1">Section 1</span></h2> -<h2> <span class="mw-headline" id="Section_2">Section 2</span></h2> +<h2><span class="mw-headline" id="Section_1">Section 1</span></h2> +<h2><span class="mw-headline" id="Section_2">Section 2</span></h2> !! end @@ -7735,7 +10759,7 @@ Link inside a section heading !! input ==Section with a [[Main Page|link]] in it== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a>]</span> <span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span></h2> +<h2><span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7747,7 +10771,7 @@ __TOC__ === title 1.1 === == title 2 == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#title_1"><span class="tocnumber">1</span> <span class="toctext">title 1</span></a> <ul> @@ -7756,10 +10780,11 @@ __TOC__ </li> <li class="toclevel-1 tocsection-3"><a href="#title_2"><span class="tocnumber">2</span> <span class="toctext">title 2</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2> +</div> + +<h2><span class="mw-headline" id="title_1">title 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h3><span class="mw-headline" id="title_1.1">title 1.1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h2><span class="mw-headline" id="title_2">title 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -7781,10 +10806,10 @@ The line above must have a trailing space! --> <!-- --> But just in case it doesn't... !! result -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D">=</span></h1> +<h1><span class="mw-headline" id=".3D">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h1> <p>The line above must have a trailing space! </p> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D_2">=</span></h1> +<h1><span class="mw-headline" id=".3D_2">=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a><span class="mw-editsection-bracket">]</span></span></h1> <p>But just in case it doesn't... </p> !! end @@ -7811,7 +10836,7 @@ section 5 !! result <p>The tooltips shall not show entities to the user (ie. be double escaped) </p> -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#text_.3E_text"><span class="tocnumber">1</span> <span class="toctext">text > text</span></a></li> <li class="toclevel-1 tocsection-2"><a href="#text_.3C_text"><span class="tocnumber">2</span> <span class="toctext">text < text</span></a></li> @@ -7819,20 +10844,21 @@ section 5 <li class="toclevel-1 tocsection-4"><a href="#text_.27_text"><span class="tocnumber">4</span> <span class="toctext">text ' text</span></a></li> <li class="toclevel-1 tocsection-5"><a href="#text_.22_text"><span class="tocnumber">5</span> <span class="toctext">text " text</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: text > text">edit</a>]</span> <span class="mw-headline" id="text_.3E_text"> text > text </span></h2> +</div> + +<h2><span class="mw-headline" id="text_.3E_text">text > text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: text > text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 1 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: text < text">edit</a>]</span> <span class="mw-headline" id="text_.3C_text"> text < text </span></h2> +<h2><span class="mw-headline" id="text_.3C_text">text < text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: text < text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 2 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: text & text">edit</a>]</span> <span class="mw-headline" id="text_.26_text"> text & text </span></h2> +<h2><span class="mw-headline" id="text_.26_text">text & text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: text & text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 3 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: text ' text">edit</a>]</span> <span class="mw-headline" id="text_.27_text"> text ' text </span></h2> +<h2><span class="mw-headline" id="text_.27_text">text ' text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: text ' text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 4 </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: text " text">edit</a>]</span> <span class="mw-headline" id="text_.22_text"> text " text </span></h2> +<h2><span class="mw-headline" id="text_.22_text">text " text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: text " text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p>section 5 </p> !! end @@ -7846,18 +10872,59 @@ Headers with excess '=' characters =''italic'' heading== ==''italic'' heading= !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#foo.3D"><span class="tocnumber">1</span> <span class="toctext">foo=</span></a></li> <li class="toclevel-1 tocsection-2"><a href="#.3Dfoo"><span class="tocnumber">2</span> <span class="toctext">=foo</span></a></li> <li class="toclevel-1 tocsection-3"><a href="#italic_heading.3D"><span class="tocnumber">3</span> <span class="toctext"><i>italic</i> heading=</span></a></li> <li class="toclevel-1 tocsection-4"><a href="#.3Ditalic_heading"><span class="tocnumber">4</span> <span class="toctext">=<i>italic</i> heading</span></a></li> </ul> -</td></tr></table> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: foo=">edit</a>]</span> <span class="mw-headline" id="foo.3D">foo=</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =foo">edit</a>]</span> <span class="mw-headline" id=".3Dfoo">=foo</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: italic heading=">edit</a>]</span> <span class="mw-headline" id="italic_heading.3D"><i>italic</i> heading=</span></h1> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: =italic heading">edit</a>]</span> <span class="mw-headline" id=".3Ditalic_heading">=<i>italic</i> heading</span></h1> +</div> + +<h1><span class="mw-headline" id="foo.3D">foo=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: foo=">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id=".3Dfoo">=foo</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =foo">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id="italic_heading.3D"><i>italic</i> heading=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: italic heading=">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h1><span class="mw-headline" id=".3Ditalic_heading">=<i>italic</i> heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: =italic heading">edit</a><span class="mw-editsection-bracket">]</span></span></h1> + +!! end + +!! test +HTML headers vs TOC (bug 23393) +(__NOEDITSECTION__ for clearer output, doesn't matter here) +!! input +<h1>Header 1</h1> +== Header 1.1 == +== Header 1.2 == + +<h1>Header 2 +</h1> +== Header 2.1 == +== Header 2.2 == +__NOEDITSECTION__ +!! result +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> +<ul> +<li class="toclevel-1"><a href="#Header_1"><span class="tocnumber">1</span> <span class="toctext">Header 1</span></a> +<ul> +<li class="toclevel-2 tocsection-1"><a href="#Header_1.1"><span class="tocnumber">1.1</span> <span class="toctext">Header 1.1</span></a></li> +<li class="toclevel-2 tocsection-2"><a href="#Header_1.2"><span class="tocnumber">1.2</span> <span class="toctext">Header 1.2</span></a></li> +</ul> +</li> +<li class="toclevel-1"><a href="#Header_2"><span class="tocnumber">2</span> <span class="toctext">Header 2</span></a> +<ul> +<li class="toclevel-2 tocsection-3"><a href="#Header_2.1"><span class="tocnumber">2.1</span> <span class="toctext">Header 2.1</span></a></li> +<li class="toclevel-2 tocsection-4"><a href="#Header_2.2"><span class="tocnumber">2.2</span> <span class="toctext">Header 2.2</span></a></li> +</ul> +</li> +</ul> +</div> + +<h1><span class="mw-headline" id="Header_1">Header 1</span></h1> +<h2><span class="mw-headline" id="Header_1.1">Header 1.1</span></h2> +<h2><span class="mw-headline" id="Header_1.2">Header 1.2</span></h2> +<h1><span class="mw-headline" id="Header_2">Header 2</span></h1> +<h2><span class="mw-headline" id="Header_2.1">Header 2.1</span></h2> +<h2><span class="mw-headline" id="Header_2.2">Header 2.2</span></h2> !! end @@ -7953,7 +11020,7 @@ div with illegal double attributes !! test div with empty attribute value, space before equals !! options -disabled +parsoid !! input <div class =>HTML rocks</div> !! result @@ -7966,7 +11033,7 @@ disabled !! test div with braces in attribute value !! options -disabled +parsoid !! input <div title="{}">Foo</div> !! result @@ -7983,7 +11050,7 @@ disabled !! test div with empty attribute value, no space before equals !! options -disabled +parsoid !! input <div class=>HTML rocks</div> !! result @@ -8079,6 +11146,81 @@ I always thought &xacute; was a cute letter. ### +### Nesting tests (see bug 41545, 50604, 51081) +### + +# This test case is fixed in Parsoid by domino 1.0.12. (bug 50604) +# Note that html2wt is considerably more difficult if we use <b> in +# the test case, instead of <big> +!! test +Ensure that HTML adoption agency algorithm is properly implemented. +!! input +<big>X<big>Y</big>Z</big> +!! result +<p><big>X<big>Y</big>Z</big> +</p> +!! end + +# This was bug 41545 in the PHP parser. +!! test +Nesting of <kbd> +!! input +<kbd>X<kbd>Y</kbd>Z</kbd> +!! result +<p><kbd>X<kbd>Y</kbd>Z</kbd> +</p> +!! end + +# The following cases were bug 51081 in the PHP parser. +# Note that there are some other nestable tags (b, i, etc) which are +# not covered; see bug 51081 for discussion. +!! test +Nesting of <em> +!! input +<em>X<em>Y</em>Z</em> +!! result +<p><em>X<em>Y</em>Z</em> +</p> +!! end + +!! test +Nesting of <strong> +!! input +<strong>X<strong>Y</strong>Z</strong> +!! result +<p><strong>X<strong>Y</strong>Z</strong> +</p> +!! end + +!! test +Nesting of <q> +!! input +<q>X<q>Y</q>Z</q> +!! result +<p><q>X<q>Y</q>Z</q> +</p> +!! end + +!! test +Nesting of <ruby> +!! input +<ruby>X<ruby>Y</ruby>Z</ruby> +!! result +<p><ruby>X<ruby>Y</ruby>Z</ruby> +</p> +!! end + +!! test +Nesting of <bdo> +!! input +<bdo>X<bdo>Y</bdo>Z</bdo> +!! result +<p><bdo>X<bdo>Y</bdo>Z</bdo> +</p> +!! end + + +### ### Media links ### @@ -8470,70 +11612,6 @@ MSIE CSS safety test: comment in expression !! end -!! test -CSS safety test: vertical tab -!! input -<p style="font-size: 100px; background-image:url\b(https://www.google.com/images/srpr/logo6w.png)">A</p> -!! result -<p style="/* invalid control char */">A</p> - -!! end - -!! test -MSIE CSS safety test: Fullwidth -!! input -<p style="font-size: 100px; color: expression((title='XSSed'),'red')">A</p> -<div style="top:EXPRESSION(alert())">B</div> -!! result -<p style="/* insecure input */">A</p> -<div style="/* insecure input */">B</div> - -!! end - -!! test -MSIE CSS safety test: IPA extensions -!! input -<div style="background-image:uʀʟ(javascript:alert())">A</div> -<p style="font-size: 100px; color: expʀessɪoɴ((title='XSSed'),'red')">B</p> -!! result -<div style="/* insecure input */">A</div> -<p style="/* insecure input */">B</p> - -!! end - -!! test -MSIE CSS safety test: sup/sub script -!! input -<div style="background-image:url⁽javascript:alert())">A</div> -<div style="background-image:url₍javascript:alert())">B</div> -<p style="font-size: 100px; color: expressioⁿ((title='XSSed'),'red')">C</p> -!! result -<div style="/* insecure input */">A</div> -<div style="/* insecure input */">B</div> -<p style="/* insecure input */">C</p> - -!! end - -!! test -MSIE CSS safety test: Repetition markers -!! input -<p style="font-size: 100px; color: expres〱ion((title='XSSed'),'red')">A</p> -<p style="font-size: 100px; color: expresゝion((title='XSSed'),'red')">B</p> -<p style="font-size: 100px; color: expresーion((title='XSSed'),'red')">C</p> -<p style="font-size: 100px; color: expresヽion((title='XSSed'),'red')">D</p> -<p style="font-size: 100px; color: expresﹽion((title='XSSed'),'red')">E</p> -<p style="font-size: 100px; color: expresﹼion((title='XSSed'),'red')">F</p> -<p style="font-size: 100px; color: expresーion((title='XSSed'),'red')">G</p> -!! result -<p style="/* insecure input */">A</p> -<p style="/* insecure input */">B</p> -<p style="/* insecure input */">C</p> -<p style="/* insecure input */">D</p> -<p style="/* insecure input */">E</p> -<p style="/* insecure input */">F</p> -<p style="/* insecure input */">G</p> - -!! end !! test Table attribute legitimate extension @@ -8617,7 +11695,7 @@ Expansion of multi-line templates in attribute values (bug 6255 sanity check 2) !! end ### -### Parser hooks (see maintenance/parserTestsParserHook.php for the <tag> extension) +### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension) ### !! test Parser hook: empty input @@ -8782,7 +11860,7 @@ array ( !! end ### -### (see maintenance/parserTestsStaticParserHook.php for the <statictag> extension) +### (see tests/parser/parserTestsParserHook.php for the <statictag> extension) ### !! test @@ -9014,8 +12092,10 @@ disabled !! result <ul> <li>One -</li><li>Two -</li></ul> +</li> +<li>Two +</li> +</ul> !! end @@ -9046,8 +12126,10 @@ disabled !! result <ol> <li>One -</li><li>Two -</li></ol> +</li> +<li>Two +</li> +</ol> !! end @@ -9092,12 +12174,16 @@ disabled !! result <ul> <li>One -</li><li>Two: +</li> +<li>Two: <ul> <li>Sub-one -</li><li>Sub-two -</li></ul> -</li></ul> +</li> +<li>Sub-two +</li> +</ul> +</li> +</ul> !! end @@ -9142,21 +12228,27 @@ disabled !! result <ol> <li>One -</li><li>Two: +</li> +<li>Two: <ol> <li>Sub-one -</li><li>Sub-two -</li></ol> -</li></ol> +</li> +<li>Sub-two +</li> +</ol> +</li> +</ol> !! end !! test HTML ordered list item with parameters oddity !! input -<ol><li id="fragment">One</li></ol> +<ol><li id="fragment">One</li> +</ol> !! result -<ol><li id="fragment">One</li></ol> +<ol><li id="fragment">One</li> +</ol> !! end @@ -9208,12 +12300,13 @@ Fuzz testing: Parser14 == onmouseover= == http://__TOC__ !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a>]</span> <span class="mw-headline" id="onmouseover.3D"> onmouseover= </span></h2> -http://<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +http://<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li> </ul> -</td></tr></table> +</div> + !! end @@ -9223,7 +12316,7 @@ Fuzz testing: Parser14-table ==a== {| STYLE=__TOC__ !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2> +<h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <table style="__TOC__"> <tr><td></td></tr> </table> @@ -9369,7 +12462,7 @@ Fuzz testing: image with bogus manual thumbnail !!input [[Image:foobar.jpg|thumbnail= ]] !!result -<div class="thumb tright"><div class="thumbinner" style="width:1943px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> +<div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> !!end @@ -10380,17 +13473,33 @@ Handling of 
 in URLs !! input **irc://
a !! result -<ul><li><ul><li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a> -</li></ul> -</li></ul> +<ul> +<li><ul> +<li><a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a> +</li> +</ul> +</li> +</ul> !!end !! test -5 quotes, code coverage +1 line +5 quotes, code coverage +1 line (php) +!! options +php +!! input +''''' +!! result +!! end +# The PHP parser strips the empty tags out for giggles; parsoid doesn't. +!! test +5 quotes, code coverage +1 line (parsoid) +!! options +parsoid !! input ''''' !! result +<p><b><i></i></b></p> !! end !! test @@ -10404,43 +13513,78 @@ Special:Search page linking. !! test Say the magic word +!! options +title=[[Parser test]] !! input * {{PAGENAME}} +* {{PAGENAMEE}} +* {{FULLPAGENAME}} +* {{FULLPAGENAMEE}} * {{BASEPAGENAME}} +* {{BASEPAGENAMEE}} * {{SUBPAGENAME}} * {{SUBPAGENAMEE}} -* {{BASEPAGENAME}} -* {{BASEPAGENAMEE}} +* {{ROOTPAGENAME}} +* {{ROOTPAGENAMEE}} * {{TALKPAGENAME}} * {{TALKPAGENAMEE}} * {{SUBJECTPAGENAME}} * {{SUBJECTPAGENAMEE}} * {{NAMESPACEE}} * {{NAMESPACE}} +* {{NAMESPACENUMBER}} * {{TALKSPACE}} * {{TALKSPACEE}} * {{SUBJECTSPACE}} * {{SUBJECTSPACEE}} * {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}} !! result -<ul><li> Parser test -</li><li> Parser test -</li><li> Parser test -</li><li> Parser_test -</li><li> Parser test -</li><li> Parser_test -</li><li> Talk:Parser test -</li><li> Talk:Parser_test -</li><li> Parser test -</li><li> Parser_test -</li><li> -</li><li> -</li><li> Talk -</li><li> Talk -</li><li> -</li><li> -</li><li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a> -</li></ul> +<ul> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> Talk:Parser test +</li> +<li> Talk:Parser_test +</li> +<li> Parser test +</li> +<li> Parser_test +</li> +<li> +</li> +<li> +</li> +<li> 0 +</li> +<li> Talk +</li> +<li> Talk +</li> +<li> +</li> +<li> +</li> +<li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a> +</li> +</ul> !! end ### Note: Above tests excludes the "{{NUMBEROFADMINS}}" magic word because it generates a MySQL error when included. @@ -10459,40 +13603,40 @@ image4 |300px| centre * image6 </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image1.png</div> + <div class="thumb" style="height: 150px;">Image1.png</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image2.gif</div> + <div class="thumb" style="height: 150px;">Image2.gif</div> <div class="gallerytext"> <p>|||| </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image3</div> + <div class="thumb" style="height: 150px;">Image3</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image4</div> + <div class="thumb" style="height: 150px;">Image4</div> <div class="gallerytext"> <p>300px| centre </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Image5.svg</div> + <div class="thumb" style="height: 150px;">Image5.svg</div> <div class="gallerytext"> <p><a rel="nofollow" class="external free" href="http://///////">http://///////</a> </p> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">* image6</div> + <div class="thumb" style="height: 150px;">* image6</div> <div class="gallerytext"> </div> </div></li> @@ -10511,17 +13655,17 @@ image:foobar.jpg image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla. </gallery> !! result -<ul class="gallery" style="max-width: 226px;_width: 226px;"> +<ul class="gallery mw-gallery-traditional" style="max-width: 226px;_width: 226px;"> <li class='gallerycaption'>Foo <a href="/wiki/Main_Page" title="Main Page">Main Page</a></li> <li class="gallerybox" style="width: 105px"><div style="width: 105px"> - <div style="height: 70px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 70px;">Nonexistant.jpg</div> <div class="gallerytext"> <p>caption </p> </div> </div></li> <li class="gallerybox" style="width: 105px"><div style="width: 105px"> - <div style="height: 70px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 70px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> @@ -10556,7 +13700,7 @@ File:foobar.jpg|[[File:foobar.jpg|20px|desc|alt=inneralt]]|alt=galleryalt File:foobar.jpg|{{Test|unamedParam|alt=param}}|alt=galleryalt </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -10585,9 +13729,9 @@ image:foobar.jpg|some '''caption''' [[Main Page]] File:Foobar.jpg </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> <p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br /> caption @@ -10595,7 +13739,7 @@ caption </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> <p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br /> </p> @@ -10630,14 +13774,14 @@ image:foobar.jpg foobar.jpg </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> - <div style="height: 150px;">Nonexistant.jpg</div> + <div class="thumb" style="height: 150px;">Nonexistant.jpg</div> <div class="gallerytext"> </div> </div></li> @@ -10828,13 +13972,25 @@ disabled !! input :;;;:: !! result -<dl><dd><dl><dt><dl><dt><dl><dt><dl><dd><dl><dd> -</dd></dl> -</dd></dl> -</dt></dl> -</dt></dl> -</dt></dl> -</dd></dl> +<dl> +<dd><dl> +<dt><dl> +<dt><dl> +<dt><dl> +<dd><dl> +<dd> +</dd> +</dl> +</dd> +</dl> +</dt> +</dl> +</dt> +</dl> +</dt> +</dl> +</dd> +</dl> !!end @@ -10861,7 +14017,7 @@ Images with the "|" character in the comment !! test HTML with raw HTML ($wgRawHtml==true) !! options -rawhtml +wgRawHtml=1 !! input <html><script>alert(1);</script></html> !! result @@ -10930,6 +14086,45 @@ subpage title=[[Subpage test/L1/L2/L3]] </p> !! end +!! article +Subpage test/L1/L2/L3Sibling +!! text +Sibling article +!! endarticle + +!! test +Transclusion of a sibling page (one level up) +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +{{../L3Sibling}} +!! result +<p>Sibling article +</p> +!! end + +!! test +Transclusion of a child page +!! options +subpage title=[[Subpage test/L1/L2]] +!! input +{{/L3Sibling}} +!! result +<p>Sibling article +</p> +!! end + +!! test +Non-transclusion because of too many up levels +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +{{../../../../More than parent}} +!! result +<p>{{../../../../More than parent}} +</p> +!! end + !! test Definition list code coverage !! input @@ -10937,10 +14132,17 @@ Definition list code coverage ; title : def ;title: def !! result -<dl><dt> title  </dt><dd> def -</dd><dt> title </dt><dd> def -</dd><dt>title</dt><dd> def -</dd></dl> +<dl> +<dt> title  </dt> +<dd> def +</dd> +<dt> title </dt> +<dd> def +</dd> +<dt>title</dt> +<dd> def +</dd> +</dl> !! end @@ -11004,7 +14206,7 @@ Inclusion of !userCanEdit() content !! input {{MediaWiki:Fake}} !! result -<h2><span class="editsection">[<a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a>]</span> <span class="mw-headline" id="header">header</span></h2> +<h2><span class="mw-headline" id="header">header</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11019,7 +14221,7 @@ Out-of-order TOC heading levels =====5===== ==2== !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#2"><span class="tocnumber">1</span> <span class="toctext">2</span></a> <ul> @@ -11034,13 +14236,14 @@ Out-of-order TOC heading levels </ul> </li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2">2</span></h2> -<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a>]</span> <span class="mw-headline" id="6">6</span></h6> -<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a>]</span> <span class="mw-headline" id="3">3</span></h3> -<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a>]</span> <span class="mw-headline" id="1">1</span></h1> -<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a>]</span> <span class="mw-headline" id="5">5</span></h5> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2_2">2</span></h2> +</div> + +<h2><span class="mw-headline" id="2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h6><span class="mw-headline" id="6">6</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a><span class="mw-editsection-bracket">]</span></span></h6> +<h3><span class="mw-headline" id="3">3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a><span class="mw-editsection-bracket">]</span></span></h3> +<h1><span class="mw-headline" id="1">1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a><span class="mw-editsection-bracket">]</span></span></h1> +<h5><span class="mw-headline" id="5">5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a><span class="mw-editsection-bracket">]</span></span></h5> +<h2><span class="mw-headline" id="2_2">2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11147,14 +14350,11 @@ anchorencode encodes like the TOC generator: (bug 18431) {{anchorencode: _ +:.3A%3A&&]] }} __NOEDITSECTION__ !! result -<h3> <span class="mw-headline" id=".2B:.3A.253A.26.26.5D.5D"> _ +:.3A%3A&&]] </span></h3> +<h3><span class="mw-headline" id=".2B:.3A.253A.26.26.5D.5D">_ +:.3A%3A&&]]</span></h3> <p>.2B:.3A.253A.26.26.5D.5D </p> !! end -# Expected output in the following test is not necessarily expected (there -# should probably be <p> tags inside the <blockquote> in the output) -- it's -# only testing for well-formedness. !! test Bug 6200: blockquotes and paragraph formatting !! input @@ -11167,7 +14367,8 @@ bar baz !! result <blockquote> -foo +<p>foo +</p> </blockquote> <p>bar </p> @@ -11196,6 +14397,27 @@ bar </pre> !! end +!!test +Parsing of overlapping (improperly nested) inline html tags (PHP parser) +!!options +php +!!input +<span><s>x</span></s> +!!result +<p><span><s>x</span></s></span> +</p> +!!end + +!!test +Parsing of overlapping (improperly nested) inline html tags (Parsoid) +!!options +parsoid +!!input +<span><s>x</span></s> +!!result +<p><span><s>x</s></span><s></s> +</p> +!!end ### ### Language variants related tests @@ -11229,6 +14451,17 @@ title=[[Duna]] language=sr !! end !! test +Link to a section of a variant of this title shouldn't be parsed as self-link +!! options +title=[[Duna]] language=sr +!! input +[[Dуна]] is a self-link while [[Dunа#Foo]] and [[Dуна#Foo]] are not self-links. +!! result +<p><strong class="selflink">Dуна</strong> is a self-link while <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dunа#Foo</a> and <a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Dуна#Foo</a> are not self-links. +</p> +!! end + +!! test Link to pages in language variants !! options language=sr @@ -11377,7 +14610,7 @@ language=sr variant=sr-ec !! input == -{Naslov}- == !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Уредите одељак „Naslov“">уреди</a>]</span> <span class="mw-headline" id="-.7BNaslov.7D-"> Naslov </span></h2> +<h2><span class="mw-headline" id="-.7BNaslov.7D-">Naslov</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Уредите одељак „Naslov“">уреди</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11491,6 +14724,30 @@ This won't take interferes with the title rule. !! end !! test +Partly disable title conversion if variant == main language code +!! options +language=zh variant=zh title=[[ZH]] showtitle +!! input +-{T|zh-cn:CN;zh-tw:TW}- +!! result +ZH +<p> +</p> +!! end + +!! test +Partly disable title conversion if variant == main language code, more +!! options +language=zh variant=zh title=[[ZH]] showtitle +!! input +-{T|TW}- +!! result +ZH +<p> +</p> +!! end + +!! test Raw output of variant escape tags (R flag) !! options language=zh variant=zh-tw @@ -11568,20 +14825,17 @@ language=sr </p> !!end -!!article -Template:Bullet -!!text -* Bar -!!endarticle - !! test Bug 529: Uncovered bullet !! input * Foo {{bullet}} !! result -<ul><li> Foo -</li><li> Bar -</li></ul> +<ul> +<li> Foo +</li> +<li> Bar +</li> +</ul> !! end @@ -11596,15 +14850,30 @@ Bug 529: Uncovered bullet leaving empty list, normally removed by tidy !! input ******* Foo {{bullet}} !! result -<ul><li><ul><li><ul><li><ul><li><ul><li><ul><li><ul><li> Foo -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li></ul> -</li><li> Bar -</li></ul> +<ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li><ul> +<li> Foo +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li> Bar +</li> +</ul> !! end @@ -11636,9 +14905,12 @@ Bug 529: Uncovered bullet in parser function result !! input * Foo {{lc:{{bullet}} }} !! result -<ul><li> Foo -</li><li> bar -</li></ul> +<ul> +<li> Foo +</li> +<li> bar +</li> +</ul> !! end @@ -11694,7 +14966,7 @@ Morwen/13: Unclosed link followed by heading !! result <p>[[link </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2> +<h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11706,7 +14978,7 @@ HHP2.1: Heuristics for headings in preprocessor parenthetical structures !! result <p>{{foo| </p> -<h1> <span class="mw-headline" id="heading">heading</span></h1> +<h1><span class="mw-headline" id="heading">heading</span></h1> !! end @@ -11718,7 +14990,7 @@ HHP2.2: Heuristics for headings in preprocessor parenthetical structures !! result <p>{{foo| </p> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2> +<h2><span class="mw-headline" id="heading">heading</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -11808,8 +15080,6 @@ B</strong> # Bug 6200: <blockquote> should behave like <div> with respect to line breaks !! test Bug 6200: paragraphs inside blockquotes (no extra line breaks) -!! options -disabled !! input <blockquote>Line one @@ -11822,8 +15092,6 @@ Line two</blockquote> !! test Bug 6200: paragraphs inside blockquotes (extra line break on open) -!! options -disabled !! input <blockquote> Line one @@ -11839,8 +15107,6 @@ Line two</blockquote> !! test Bug 6200: paragraphs inside blockquotes (extra line break on close) -!! options -disabled !! input <blockquote>Line one @@ -11856,8 +15122,6 @@ Line two !! test Bug 6200: paragraphs inside blockquotes (extra line break on open and close) -!! options -disabled !! input <blockquote> Line one @@ -12078,7 +15342,7 @@ comment title=[[Main Page]] !! input pre-comment text /* External links */ removed bogus entries !! result -pre-comment text - <a href="/wiki/Main_Page#External_links" title="Main Page">→</a><span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span> +pre-comment text <a href="/wiki/Main_Page#External_links" title="Main Page">→</a><span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span> !!end !! test @@ -12310,6 +15574,40 @@ Screen !! end !! test +Verify that displaytitle handles inline CSS styles (bug 26547) - rejected value +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:<span style="display: none;">s</span>creen}} +!! result +<span style="/* attempt to bypass $wgRestrictDisplayTitle */">s</span>creen +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle handles inline CSS styles (bug 26547) - accepted value +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:<span style="color: red;">s</span>creen}} +!! result +<span style="color: red;">s</span>creen +<p>this is not the the title +</p> +!! end + +!! test preload: check <noinclude> and <includeonly> !! options preload @@ -12533,12 +15831,13 @@ title=[[Main Page]] __TOC__ == ''Lost'' episodes == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Lost_episodes"><span class="tocnumber">1</span> <span class="toctext"><i>Lost</i> episodes</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Lost episodes">edit</a>]</span> <span class="mw-headline" id="Lost_episodes"> <i>Lost</i> episodes </span></h2> +</div> + +<h2><span class="mw-headline" id="Lost_episodes"><i>Lost</i> episodes</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Lost episodes">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12550,12 +15849,13 @@ title=[[Main Page]] __TOC__ == '''should be bold''' then normal text == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#should_be_bold_then_normal_text"><span class="tocnumber">1</span> <span class="toctext"><b>should be bold</b> then normal text</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: should be bold then normal text">edit</a>]</span> <span class="mw-headline" id="should_be_bold_then_normal_text"> <b>should be bold</b> then normal text </span></h2> +</div> + +<h2><span class="mw-headline" id="should_be_bold_then_normal_text"><b>should be bold</b> then normal text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: should be bold then normal text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12567,12 +15867,13 @@ title=[[Main Page]] __TOC__ == Image [[Image:foobar.jpg]] == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Image"><span class="tocnumber">1</span> <span class="toctext">Image</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Image">edit</a>]</span> <span class="mw-headline" id="Image"> Image <a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> </span></h2> +</div> + +<h2><span class="mw-headline" id="Image">Image <a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Image">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12584,12 +15885,13 @@ title=[[Main Page]] __TOC__ == <blockquote>Quote</blockquote> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Quote">edit</a>]</span> <span class="mw-headline" id="Quote"> <blockquote>Quote</blockquote> </span></h2> +</div> + +<h2><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12603,12 +15905,13 @@ __TOC__ <small>Hanc marginis exiguitas non caperet.</small> QED !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Proof:_2_.3C_3"><span class="tocnumber">1</span> <span class="toctext">Proof: 2 < 3</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Proof: 2 < 3">edit</a>]</span> <span class="mw-headline" id="Proof:_2_.3C_3"> Proof: 2 < 3 </span></h2> +</div> + +<h2><span class="mw-headline" id="Proof:_2_.3C_3">Proof: 2 < 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Proof: 2 < 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2> <p><small>Hanc marginis exiguitas non caperet.</small> QED </p> @@ -12622,14 +15925,15 @@ __TOC__ == <i>Foo</i> <blockquote>Bar</blockquote> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar"> <i>Foo</i> <b>Bar</b> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> <i>Foo</i> <blockquote>Bar</blockquote> </span></h2> +</div> + +<h2><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12641,14 +15945,15 @@ __TOC__ == <sup class="a > b">Evilbye</sup> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#Hello"><span class="tocnumber">1</span> <span class="toctext"><sup>Hello</sup></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#b.22.3EEvilbye"><span class="tocnumber">2</span> <span class="toctext"><sup> b">Evilbye</sup></span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Hello">edit</a>]</span> <span class="mw-headline" id="Hello"> <sup class="in-h2">Hello</sup> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">Evilbye">edit</a>]</span> <span class="mw-headline" id="b.22.3EEvilbye"> <sup> b">Evilbye</sup> </span></h2> +</div> + +<h2><span class="mw-headline" id="Hello"><sup class="in-h2">Hello</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Hello">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="b.22.3EEvilbye"><sup> b">Evilbye</sup></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: b">Evilbye">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12666,7 +15971,7 @@ __TOC__ == <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> == !! result -<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div> +<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div> <ul> <li class="toclevel-1 tocsection-1"><a href="#C.2B.2B"><span class="tocnumber">1</span> <span class="toctext"><span dir="ltr">C++</span></span></a></li> <li class="toclevel-1 tocsection-2"><a href="#.D7.96.D7.91.D7.A0.D7.92.21"><span class="tocnumber">2</span> <span class="toctext"><span dir="rtl">זבנג!</span></span></a></li> @@ -12674,12 +15979,13 @@ __TOC__ <li class="toclevel-1 tocsection-4"><a href="#All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span class="tocnumber">4</span> <span class="toctext"><span>All attributes on these span tags must be deleted from the TOC</span></span></a></li> <li class="toclevel-1 tocsection-5"><a href="#Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span class="tocnumber">5</span> <span class="toctext"><span dir="ltr">Attributes after dir on these span tags must be deleted from the TOC</span></span></a></li> </ul> -</td></tr></table> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: C++">edit</a>]</span> <span class="mw-headline" id="C.2B.2B"> <span dir="ltr">C++</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: זבנג!">edit</a>]</span> <span class="mw-headline" id=".D7.96.D7.91.D7.A0.D7.92.21"> <span dir="rtl">זבנג!</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: The attributes on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: All attributes on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"> <span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span> </span></h2> -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Attributes after dir on these span tags must be deleted from the TOC">edit</a>]</span> <span class="mw-headline" id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"> <span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span> </span></h2> +</div> + +<h2><span class="mw-headline" id="C.2B.2B"><span dir="ltr">C++</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: C++">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id=".D7.96.D7.91.D7.A0.D7.92.21"><span dir="rtl">זבנג!</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: זבנג!">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="The_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic">The attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: The attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="All_attributes_on_these_span_tags_must_be_deleted_from_the_TOC"><span style="font-style: italic" dir="ltr">All attributes on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: All attributes on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Attributes_after_dir_on_these_span_tags_must_be_deleted_from_the_TOC"><span dir="ltr" style="font-style: italic">Attributes after dir on these span tags must be deleted from the TOC</span></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Attributes after dir on these span tags must be deleted from the TOC">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12696,7 +16002,7 @@ title=[[Main Page]] !! input {{int:Bug32057}} !! result -<h2><span class="editsection">[<a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Headline text">edit</a>]</span> <span class="mw-headline" id="Headline_text"> Headline text </span></h2> +<h2><span class="mw-headline" id="Headline_text">Headline text</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&action=edit&section=1" title="Edit section: Headline text">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12798,7 +16104,7 @@ nowiki inside link inside heading (bug 18295) !! input ==[[foo|x<nowiki>y</nowiki>z]]== !! result -<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: xyz">edit</a>]</span> <span class="mw-headline" id="xyz"><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">xyz</a></span></h2> +<h2><span class="mw-headline" id="xyz"><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">xyz</a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: xyz">edit</a><span class="mw-editsection-bracket">]</span></span></h2> !! end @@ -12837,7 +16143,7 @@ Gallery override link with WikiLink (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/InterWikiLink"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12856,7 +16162,7 @@ Gallery override link with absolute external link (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12875,7 +16181,7 @@ Gallery override link with malicious javascript (bug 34852) File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascript code!'); </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/%22_onclick%3D%22alert(%27malicious_javascript_code!%27);"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12894,7 +16200,7 @@ Gallery with invalid title as link (bug 43964) File:foobar.jpg|link=< </gallery> !! result -<ul class="gallery"> +<ul class="gallery mw-gallery-traditional"> <li class="gallerybox" style="width: 155px"><div style="width: 155px"> <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> <div class="gallerytext"> @@ -12925,6 +16231,19 @@ abc !! end !!test +Special parser function +!! input +{{#special:RandomPage}} +{{#special:BaDtItLe}} +{{#special:Foobar}} +!! result +<p>Special:Random +Special:Badtitle +Special:Foobar +</p> +!! end + +!!test Bug 34939 - Case insensitive link parsing ([HttP://]) !! input [HttP://MediaWiki.Org/] @@ -12951,6 +16270,30 @@ HttP://MediaWiki.Org/ </p> !! end +!!test +Disable TOC +!! options +notoc +!! input +Lead +== Section 1 == +== Section 2 == +== Section 3 == +== Section 4 == +== Section 5 == +!! result +<p>Lead +</p> + +<h2><span class="mw-headline" id="Section_1">Section 1</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_2">Section 2</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 2">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_3">Section 3</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 3">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_4">Section 4</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 4">edit</a><span class="mw-editsection-bracket">]</span></span></h2> +<h2><span class="mw-headline" id="Section_5">Section 5</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 5">edit</a><span class="mw-editsection-bracket">]</span></span></h2> + +!! end + + ### ### Parsoids-specific tests ### Parsoid-PHP parser incompatibilities @@ -12958,25 +16301,433 @@ HttP://MediaWiki.Org/ !!test 1. SOL-sensitive wikitext tokens as template-args !!options -disabled +parsoid=wt2html,wt2wt !!input {{echo|*a}} {{echo|#a}} {{echo|:a}} !!result -<p>*a -#a -:a -</p> +<span about="#mwt1" typeof="mw:Transclusion"> +</span><ul about="#mwt1"><li>a</li> +</ul> +<span about="#mwt2" typeof="mw:Transclusion"> +</span><ol about="#mwt2"><li>a</li> +</ol> +<span about="#mwt3" typeof="mw:Transclusion"> +</span><dl about="#mwt3"><dd>a</dd> +</dl> +!!end + +#### ---------------------------------------------------------------- +#### Parsoid-only testing of Parsoid's impl of <ref> and <references> +#### tags. Parsoid's output for these tags differs from that of the +#### PHP parser. +#### ---------------------------------------------------------------- + +!!test +Ref: 1. ref-location should be replaced with an index span +!!options +parsoid +!!input +A <ref>foo</ref> +B <ref name="x">foo</ref> +C <ref name="y" /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-2">[2]</a></span> +C <span about="#mwt3" class="reference" data-mw='{"name":"ref","attrs":{"name":"y"}}' id="cite_ref-y-3-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-y-3">[3]</a></span></p> +!!end + +!!test +Ref: 2. ref-tags with identical names should all get the same index +!!options +parsoid +!!input +A <ref name="x">foo</ref> +B <ref name="x" /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span></p> +!!end + +!!test +Ref: 3. spaces in ref-names should be ignored +!!options +parsoid +!!input +A <ref name="x">foo</ref> +B <ref name=" x " /> +C <ref name= x /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"x"}}' id="cite_ref-x-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +B <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span> +C <span about="#mwt3" class="reference" data-mw='{"name":"ref","attrs":{"name":"x"}}' id="cite_ref-x-1-2" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-x-1">[1]</a></span></p> +!!end + +!!test +Ref: 4. 'constructor' should be accepted as a valid ref-name +(NOTE: constructor is a predefined property in JS and constructor as a ref-name can clash with it if not handled properly) +!!options +parsoid +!!input +A <ref name="constructor">foo</ref> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"constructor"}}' id="cite_ref-constructor-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-constructor-1">[1]</a></span></p> +!!end + +!!test +Ref: 5. body should accept generic wikitext +!!options +parsoid +!!input +A <ref> + This is a '''[[bolded link]]''' and this is a {{echo|transclusion}} +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"This is a <b data-parsoid=\"{&quot;dsr&quot;:[19,40,3,3]}\"><a rel=\"mw:WikiLink\" href=\"./Bolded_link\" data-parsoid=\"{&quot;stx&quot;:&quot;simple&quot;,&quot;a&quot;:{&quot;href&quot;:&quot;./Bolded_link&quot;},&quot;sa&quot;:{&quot;href&quot;:&quot;bolded link&quot;},&quot;dsr&quot;:[22,37,2,2]}\">bolded link</a></b> and this is a <span about=\"#mwt5\" typeof=\"mw:Transclusion\" data-mw=\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;transclusion&quot;}},&quot;i&quot;:0}}]}\" data-parsoid=\"{&quot;dsr&quot;:[55,76,null,null],&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]]}\">transclusion</span>\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> This is a <b><a rel="mw:WikiLink" href="./Bolded_link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span> +</li> +</ol> +!!end + +!!test +Ref: 6. indent-pres should not be output in ref-body +!!options +parsoid +!!input +A <ref> + foo + bar + baz +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo\n bar\n baz\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt3" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo + bar + baz +</li> +</ol> +!!end + +!!test +Ref: 7. No p-wrapping in ref-body +!!options +parsoid +!!input +A <ref> +foo + +bar + + +baz + + + +booz +</ref> + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo\n\nbar\n\n\nbaz\n\n\n\nbooz\n"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo + +bar + + +baz + + + +booz +</li> +</ol> +!!end + +!!test +Ref: 8. transclusion wikitext has lower precedence +!!options +parsoid +!!input +A <ref> foo {{echo|</ref> B C}} + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo <span typeof=\"mw:Nowiki\" data-parsoid=\"{&quot;src&quot;:&quot;{{&quot;,&quot;dsr&quot;:[12,14,0,0]}\">{{</span>echo|"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C<span typeof="mw:Nowiki">}}</span></p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <span typeof="mw:Nowiki">{{</span>echo|</li> +</ol> +!!end + +!!test +Ref: 9. unclosed comments should not leak out of ref-body +!!options +parsoid +!!input +A <ref> foo <!--</ref> B C + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo <!---->"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C</p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <!----></li> +</ol> +!!end + +!!test +Ref: 10. Unclosed HTML tags should not leak out of ref-body +!!options +parsoid +!!input +A <ref> <b> foo </ref> B C + +<references /> +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"<b data-parsoid=\"{&quot;stx&quot;:&quot;html&quot;,&quot;autoInsertedEnd&quot;:true,&quot;dsr&quot;:[8,16,3,0]}\"> foo </b>"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B C</p> + +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> <b> foo </b></li> +</ol> +!!end + +!!test +Ref: 11. ref-tags acts like an inline element wrt P-wrapping +!!options +parsoid +!!input +A <ref>foo</ref> B +C <ref>bar</ref> D +!!result +<p>A <span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> B +C <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span> D</p> +!!end + +!!test +Ref: 12. ref-tags act as trailing newline migration barrier +!!options +parsoid +!!input +<!--the newline at the end of this line moves out of the p-tag-->a + +b<!--the newline at the end of this line stays inside the p-tag--> <ref /> +<ref /> + +c +!!result +<p><!--the newline at the end of this line moves out of the p-tag-->a</p> + + +<p>b<!--the newline at the end of this line stays inside the p-tag--> <span about="#mwt1" class="reference" data-mw='{"name":"ref","attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +<span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span></p> + + +<p>c</p> +!!end + +!!test +Ref: 13. ref-tags are not SOL-transparent and block indent-pres +!!options +parsoid +!!input +<ref>foo</ref> A +<ref>bar +</ref> B +!!result +<p><span about="#mwt1" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> A +<span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"bar\n"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span> B</p> +!!end + +!!test +Ref: 14. A nested ref-tag should be emitted as plain text +!!options +parsoid +!!input +<ref>foo <ref>bar</ref> baz</ref> + +<references /> +!!result +<p><span about="#mwt1" class="reference" data-mw="{"name":"ref","body":{"html":"foo &lt;ref&gt;bar&lt;/ref&gt; baz"},"attrs":{}}" id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt2" data-mw="{"name":"references","attrs":{}}"> +<li about="#cite_note-1" id="cite_note-1" data-parsoid="{}"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo <ref>bar</ref> baz</li> +</ol> +!!end + +!!test +Ref: 15. ref-tags with identical names should get identical indexes +!!options +parsoid +!!input +A1 <ref name="a">foo</ref> A2 <ref name="a" /> +B1 <ref name="b" /> B2 <ref name="b">bar</ref> + +<references /> +!!result +<p>A1 <span about="#mwt3" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> A2 <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> +B1 <span about="#mwt7" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span> B2 <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-1" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy">↑ <a href="#cite_ref-a-1-0">1.0</a> <a href="#cite_ref-a-1-1">1.1</a></span> foo</li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy">↑ <a href="#cite_ref-b-2-0">2.0</a> <a href="#cite_ref-b-2-1">2.1</a></span> bar</li> +</ol> +!!end + +!!test +References: 1. references tag without any refs should be handled properly +!!options +parsoid +!!input +<references /> +!!result +<ol about="#mwt2" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'></ol> +!!end + +!!test +References: 2. references tag with group only outputs references from that group +!!options +parsoid +!!input +A <ref group="a">foo</ref> +B <ref group="b">bar</ref> + +<references group='a' /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"group":"b"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[b 1]</a></span></p> + +<ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li> +</ol> +!!end + +!!test +References: 3. ref list should be cleared after processing references +!!options +parsoid +!!input +A <ref>foo</ref> + +<references /> + +B <ref>bar</ref> + +<references /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt4" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo</li> +</ol> + +<p>B <span about="#mwt6" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt8" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bar</li> +</ol> !!end +!!test +References: 4. only referenced group should be cleared after processing references +!!options +parsoid +!!input +A <ref group="a">afoo</ref> +B <ref>bfoo</ref> + +<references group="a"/> + +C <ref>cfoo</ref> + +<references /> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"afoo"},"attrs":{"group":"a"}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[a 1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bfoo"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"<ref>bfoo</ref>","dsr":[30,45,5,6]}'><a href="#cite_note-1">[1]</a></span></p> + +<ol about="#mwt6" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{"group":"a"}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> afoo</li> +</ol> + +<p>C <span about="#mwt8" class="reference" data-mw='{"name":"ref","body":{"html":"cfoo"},"attrs":{}}' id="cite_ref-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-2">[2]</a></span></p> + +<ol about="#mwt10" class="references" typeof="mw:Extension/references" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> bfoo</li><li about="#cite_note-2" id="cite_note-2"><span rel="mw:referencedBy"><a href="#cite_ref-2-0">↑</a></span> cfoo</li> +</ol> +!!end + +!!test +References: 5. ref tags in references should be processed while ignoring all other content +!!options +parsoid +!!input +A <ref name="a" /> +B <ref name="b">bar</ref> + +<references> +<ref name="a">foo</ref> +This should just get lost. +</references> +!!result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","attrs":{"name":"a"}}' id="cite_ref-a-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-a-1">[1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","body":{"html":"bar"},"attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","body":{"extsrc":"<ref name=\"a\">foo</ref>\nThis should just get lost.","html":"\n<span about=\"#mwt8\" class=\"reference\" data-mw=\"{&quot;name&quot;:&quot;ref&quot;,&quot;body&quot;:{&quot;html&quot;:&quot;foo&quot;},&quot;attrs&quot;:{&quot;name&quot;:&quot;a&quot;}}\" rel=\"dc:references\" typeof=\"mw:Extension/ref\"><a href=\"#cite_note-a-1\">[1]</a></span>\n"},"attrs":{}}'><li about="#cite_note-a-1" id="cite_note-a-1"><span rel="mw:referencedBy"><a href="#cite_ref-a-1-0">↑</a></span> foo</li><li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> bar</li> +</ol> +!!end + +!!test +References: 6. <references /> from a transclusion +!!options +parsoid +!!input +{{echo|<references />}} +!!result +<ol class="references" about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<references />"}},"i":0}}]}'></ol> +!!end + +!! test +References: 7. Multiple references tags (one without and one with nested refs) should be correctly handled +!! options +parsoid +!! input +A <ref>foo bar for a</ref> +B <ref name="b" /> + +<references /> + +<references> +<ref name="b">foo</ref> +</references> +!! result +<p>A <span about="#mwt2" class="reference" data-mw='{"name":"ref","body":{"html":"foo bar for a"},"attrs":{}}' id="cite_ref-1-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-1">[1]</a></span> +B <span about="#mwt4" class="reference" data-mw='{"name":"ref","attrs":{"name":"b"}}' id="cite_ref-b-2-0" rel="dc:references" typeof="mw:Extension/ref"><a href="#cite_note-b-2">[2]</a></span></p> + +<ol class="references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'> +<li about="#cite_note-1" id="cite_note-1"><span rel="mw:referencedBy"><a href="#cite_ref-1-0">↑</a></span> foo bar for a</li> +<li about="#cite_note-b-2" id="cite_note-b-2"><span rel="mw:referencedBy"><a href="#cite_ref-b-2-0">↑</a></span> </li> +</ol> + +<ol class="references" typeof="mw:Extension/references" about="#mwt8" data-mw='{"name":"references","body":{"extsrc":"<ref name=\"b\">foo</ref>","html":"\n<span about=\"#mwt10\" class=\"reference\" data-mw=\"{&quot;name&quot;:&quot;ref&quot;,&quot;body&quot;:{&quot;html&quot;:&quot;foo&quot;},&quot;attrs&quot;:{&quot;name&quot;:&quot;b&quot;}}\" rel=\"dc:references\" typeof=\"mw:Extension/ref\"><a href=\"#cite_note-b-1\">[1]</a></span>\n"},"attrs":{}}'> +<li about="#cite_note-b-1" id="cite_note-b-1"><span rel="mw:referencedBy">↑</span> foo</li> +</ol> +!! end + +#### ---------------------------------------------------------------- #### The following section of tests are primarily to test -#### wikitext escaping capabilities of Parsoid. -#### A lot of the tests are disabled for the PHP parser either -#### because of minor newline diffs or other reasons. -#### As Parsoid serializer can handle newlines and other HTML -#### more robustly, some of these tests might get reenabled -#### for the PHP parser. +#### wikitext escaping capabilities of Parsoid. Given that +#### escaping can be done any number of ways, the wikitext (input) +#### is always adjusted to reflect how Parsoid adds nowiki +#### escape tags. +#### +#### We are marking several tests as parsoid-only since the +#### HTML in the result section is different from what the +#### PHP parser generates for it. +#### ---------------------------------------------------------------- + #### --------------- Headings --------------- #### 0. Unnested @@ -12989,45 +16740,62 @@ disabled #### ---------------------------------------- !! test Headings: 0. Unnested +!! options +parsoid !! input <nowiki>=foo=</nowiki> -<nowiki>=foo</nowiki>''a''= +<nowiki> =foo= </nowiki> +<!--cmt--> +<nowiki>=foo=</nowiki> + +=foo''a''<nowiki>=</nowiki> !! result -<p>=foo= -</p><p>=foo<i>a</i>= -</p> +<p><span typeof="mw:Nowiki">=foo=</span></p> + +<p><span typeof="mw:Nowiki"> =foo= </span> +<!--cmt--> +<span typeof="mw:Nowiki">=foo=</span></p> + +<p>=foo<i>a</i><span typeof="mw:Nowiki">=</span></p> !!end !! test Headings: 1. Nested inside html !! options -disabled +parsoid !! input =<nowiki>=foo=</nowiki>= + ==<nowiki>=foo=</nowiki>== + ===<nowiki>=foo=</nowiki>=== + ====<nowiki>=foo=</nowiki>==== + =====<nowiki>=foo=</nowiki>===== + ======<nowiki>=foo=</nowiki>====== !! result -<h1>=foo=</h1> -<h2>=foo=</h2> -<h3>=foo=</h3> -<h4>=foo=</h4> -<h5>=foo=</h5> -<h6>=foo=</h6> +<h1><span typeof="mw:Nowiki">=foo=</span></h1> +<h2><span typeof="mw:Nowiki">=foo=</span></h2> +<h3><span typeof="mw:Nowiki">=foo=</span></h3> +<h4><span typeof="mw:Nowiki">=foo=</span></h4> +<h5><span typeof="mw:Nowiki">=foo=</span></h5> +<h6><span typeof="mw:Nowiki">=foo=</span></h6> !!end !! test Headings: 2. Outside heading nest on a single line <h1>foo</h1>*bar !! options -disabled +parsoid !! input =foo= -<nowiki>*bar</nowiki> +<nowiki>*</nowiki>bar + =foo= =bar + =foo= <nowiki>=bar=</nowiki> !! result @@ -13039,44 +16807,75 @@ disabled !! test Headings: 3. Nested inside html with wikitext split by html tags !! options -disabled +parsoid !! input -=<nowiki>=</nowiki>'''bold'''foo== +=='''bold'''<nowiki>foo=</nowiki>= !! result -<h1>=<b>bold</b>foo=</h1> +<h1>=<b>bold</b><span typeof="mw:Nowiki">foo=</span></h1> !!end !! test -Headings: 4. No escaping needed (testing just h1 and h2) +Headings: 4a. No escaping needed (testing just h1 and h2) !! options -disabled +parsoid !! input ==foo= + =foo== + += =foo= = + +==foo= bar= + ===foo== + ==foo=== + =''=''foo== -=== + +=<nowiki>=</nowiki>= !! result <h1>=foo</h1> <h1>foo=</h1> +<h1> =foo= </h1> +<h1>=foo= bar</h1> <h2>=foo</h2> <h2>foo=</h2> <h1><i>=</i>foo=</h1> -<h1>=</h1> +<h1><span typeof="mw:Nowiki">=</span></h1> +!!end + +!! test +Headings: 4b. No escaping needed (inside p-tags) +!! options +parsoid +!! input +=== +=foo= x +=foo= <s></s> +!! result +<p>=== +=foo= x +=foo= <s></s> +</p> !!end !! test Headings: 5. Empty headings !! options -disabled +parsoid !! input -=<nowiki></nowiki>= -==<nowiki></nowiki>== -===<nowiki></nowiki>=== -====<nowiki></nowiki>==== -=====<nowiki></nowiki>===== -======<nowiki></nowiki>====== +=<nowiki/>= + +==<nowiki/>== + +===<nowiki/>=== + +====<nowiki/>==== + +=====<nowiki/>===== + +======<nowiki/>====== !! result <h1></h1> <h2></h2> @@ -13087,16 +16886,87 @@ disabled !!end !! test -Headings: 6. Heading chars in SOL context +Headings: 6a. Heading chars in SOL context (with trailing spaces) !! options -disabled +parsoid +!! input +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> + +<nowiki>=a=</nowiki> +!! result +<p>=a=</p> +<p>=a= </p> +<p>=a= </p> +<p>=a= </p> +!!end + +!! test +Headings: 6b. Heading chars in SOL context (with trailing newlines) +!! options +parsoid !! input -<!--cmt--><nowiki>=h1=</nowiki> +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> + +<nowiki>=a= +b</nowiki> !! result -<p><!--cmt-->=h1= +<p>=a= +b</p> +<p>=a= +b</p> +<p>=a= +b</p> +<p>=a= +b</p> </p> !!end +!! test +Headings: 6c. Heading chars in SOL context (leading newline break) +!! options +parsoid +!! input +a +<nowiki>=b=</nowiki> +!! result +<p>a +=b=</p> +!!end + +!! test +Headings: 6d. Heading chars in SOL context (with interspersed comments) +!! options +parsoid +!! input +<!--c0--><nowiki>=a=</nowiki> +<!--c1--> +<nowiki>=a=</nowiki> <!--c2--> <!--c3--> +!! result +<p><!--c0-->=a=</p> +<p><!--c1-->=a= <!--c2--> <!--c3--></p> +!!end + +!! test +Headings: 6d. Heading chars in SOL context (No escaping needed) +!! options +parsoid=html2wt +!! input +=a=<div>b</div> +!! result +=a=<div>b</div> +!!end + #### --------------- Lists --------------- #### 0. Outside nests (*foo, etc.) #### 1. Nested inside html <ul><li>*foo</li></ul> @@ -13111,9 +16981,9 @@ disabled !! test Lists: 0. Outside nests !! input -<nowiki>*foo</nowiki> +<nowiki>*</nowiki>foo -<nowiki>#foo</nowiki> +<nowiki>#</nowiki>foo !! result <p>*foo </p><p>#foo @@ -13139,22 +17009,38 @@ Lists: 1. Nested inside html #<nowiki>;foo</nowiki> !! result -<ul><li>*foo -</li></ul> -<ul><li>#foo -</li></ul> -<ul><li>:foo -</li></ul> -<ul><li>;foo -</li></ul> -<ol><li>*foo -</li></ol> -<ol><li>#foo -</li></ol> -<ol><li>:foo -</li></ol> -<ol><li>;foo -</li></ol> +<ul> +<li>*foo +</li> +</ul> +<ul> +<li>#foo +</li> +</ul> +<ul> +<li>:foo +</li> +</ul> +<ul> +<li>;foo +</li> +</ul> +<ol> +<li>*foo +</li> +</ol> +<ol> +<li>#foo +</li> +</ol> +<ol> +<li>:foo +</li> +</ol> +<ol> +<li>;foo +</li> +</ol> !!end @@ -13170,15 +17056,24 @@ Lists: 2. Inside definition lists :<nowiki>:foo</nowiki> !! result -<dl><dt>;foo -</dt></dl> -<dl><dt>:foo -</dt></dl> -<dl><dt>:foo -</dt><dd>bar -</dd></dl> -<dl><dd>:foo -</dd></dl> +<dl> +<dt>;foo +</dt> +</dl> +<dl> +<dt>:foo +</dt> +</dl> +<dl> +<dt>:foo +</dt> +<dd>bar +</dd> +</dl> +<dl> +<dd>:foo +</dd> +</dl> !!end @@ -13189,17 +17084,21 @@ Lists: 3. Only bullets at start of text should be escaped *<nowiki>*foo</nowiki>''it''*bar !! result -<ul><li>*foo*bar -</li></ul> -<ul><li>*foo<i>it</i>*bar -</li></ul> +<ul> +<li>*foo*bar +</li> +</ul> +<ul> +<li>*foo<i>it</i>*bar +</li> +</ul> !!end !! test Lists: 4. No escapes needed !! options -disabled +parsoid !! input *foo*bar @@ -13207,12 +17106,18 @@ disabled *[[Foo]]: bar !! result -<ul><li>foo*bar -</li></ul> -<ul><li><i>foo</i>*bar -</li></ul> -<ul><li><a href="Foo" rel="mw:WikiLink">Foo</a>: bar -</li></ul> +<ul> +<li>foo*bar +</li> +</ul> +<ul> +<li><i>foo</i>*bar +</li> +</ul> +<ul> +<li><a rel="mw:WikiLink" href="Foo">Foo</a>: bar +</li> +</ul> !!end !! test @@ -13224,39 +17129,54 @@ Lists: 5. No unnecessary escapes *[[bar <span><nowiki>[[foo]]</nowiki></span> -*<nowiki>]]bar </nowiki><span><nowiki>[[foo]]</nowiki></span> +*]]bar <span><nowiki>[[foo]]</nowiki></span> *=bar <span>foo]]</span>= + +* <s></s>: a !! result -<ul><li> bar <span>[[foo]]</span> -</li></ul> -<ul><li>=bar <span>[[foo]]</span> -</li></ul> -<ul><li>[[bar <span>[[foo]]</span> -</li></ul> -<ul><li>]]bar <span>[[foo]]</span> -</li></ul> -<ul><li>=bar <span>foo]]</span>= -</li></ul> +<ul> +<li> bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>=bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>[[bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>]]bar <span>[[foo]]</span> +</li> +</ul> +<ul> +<li>=bar <span>foo]]</span>= +</li> +</ul> +<ul> +<li> <s></s>: a +</li> +</ul> !!end !! test Lists: 6. Escape bullets in SOL position !! options -disabled +parsoid !! input <!--cmt--><nowiki>*foo</nowiki> !! result -<p><!--cmt-->*foo -</p> +<p><!--cmt--><span typeof="mw:Nowiki">*foo</span></p> !!end !! test Lists: 7. Escape bullets in a multi-line context !! input -<nowiki>a -*b</nowiki> +a +<nowiki>*</nowiki>b !! result <p>a *b @@ -13270,18 +17190,15 @@ Lists: 7. Escape bullets in a multi-line context !! test HRs: 1. Single line !! options -disabled +parsoid !! input ----- -<nowiki>----</nowiki> ----- -<nowiki>=foo=</nowiki> ----- -<nowiki>*foo</nowiki> +----<nowiki>----</nowiki> +----=foo= +----*foo !! result -<hr/>---- -<hr/>=foo= -<hr/>*foo +<hr><span typeof="mw:Nowiki">----</span> +<hr>=foo= +<hr>*foo !! end #### --------------- Tables --------------- @@ -13344,102 +17261,92 @@ Tables: 1d. No escaping needed !! test Tables: 2a. Nested in td !! options -disabled +parsoid !! input {| |<nowiki>foo|bar</nowiki> |} !! result -<table> -<tr><td>foo|bar -</td></tr></table> - +<table><tbody><tr> +<td><span typeof="mw:Nowiki">foo|bar</span></td></tr></tbody></table> !! end !! test Tables: 2b. Nested in td !! options -disabled +parsoid !! input {| |<nowiki>foo||bar</nowiki> |''it''<nowiki>foo||bar</nowiki> |} !! result -<table> -<tr><td>foo||bar -</td><td><i>it</i>foo||bar -</td></tr></table> - +<table><tbody><tr> +<td><span typeof="mw:Nowiki">foo||bar</span></td> +<td><i>it</i><span typeof="mw:Nowiki">foo||bar</span></td></tr></tbody></table> !! end !! test Tables: 2c. Nested in td -- no escaping needed !! options -disabled +parsoid !! input {| |foo!!bar |} !! result -<table> -<tr><td>foo!!bar -</td></tr></table> +<table><tbody><tr><td>foo!!bar +</td></tr></tbody></table> !! end !! test Tables: 3a. Nested in th !! options -disabled +parsoid !! input {| !foo!bar |} !! result -<table> -<tr><th>foo!bar -</th></tr></table> +<table><tbody><tr><th>foo!bar +</th></tr></tbody></table> !! end !! test Tables: 3b. Nested in th !! options -disabled +parsoid !! input {| !<nowiki>foo!!bar</nowiki> |} !! result <table> -<tr><th>foo!!bar -</th></tr></table> - +<tbody><tr><th><span typeof="mw:Nowiki">foo!!bar</span></th></tr> +</tbody></table> !! end !! test Tables: 3c. Nested in th -- no escaping needed !! options -disabled +parsoid !! input {| -!foo||bar +!<nowiki>foo||bar</nowiki> |} !! result -<table> -<tr><th>foo||bar -</th></tr></table> - +<table><tbody><tr> +<th><span typeof="mw:Nowiki">foo||bar</span></th></tr></tbody></table> !! end !! test Tables: 4a. Escape - !! options -disabled +parsoid !! input {| -|- !-bar |- |<nowiki>-bar</nowiki> @@ -13447,17 +17354,16 @@ disabled !! result <table><tbody> <tr><th>-bar</th></tr> -<tr><td>-bar</td></tr> -</tbody></table> +<tr> +<td><span typeof="mw:Nowiki">-bar</span></td></tr></tbody></table> !! end !! test Tables: 4b. Escape + !! options -disabled +parsoid !! input {| -|- !+bar |- |<nowiki>+bar</nowiki> @@ -13465,32 +17371,48 @@ disabled !! result <table><tbody> <tr><th>+bar</th></tr> -<tr><td>+bar</td></tr> -</tbody></table> +<tr> +<td><span typeof="mw:Nowiki">+bar</span></td></tr></tbody></table> !! end !! test Tables: 4c. No escaping needed !! options -disabled +parsoid !! input {| -|- |foo-bar |foo+bar |- |''foo''-bar |''foo''+bar +|- +|foo +bar|baz ++bar +-bar |} !! result <table><tbody> <tr><td>foo-bar</td><td>foo+bar</td></tr> <tr><td><i>foo</i>-bar</td><td><i>foo</i>+bar</td></tr> +<tr><td>foo +<p>bar|baz ++bar +-bar</p></td></tr> </tbody></table> !! end +### SSS FIXME: Disabled right now because accurate html2wt +### on this snippet requires data-parsoid flags that we've +### stripped out of these tests. We should scheme how we +### we want to handle these kind of tests that require +### data-parsoid flags for accurate html2wt serialization + !! test Tables: 4d. No escaping needed +!! options +disabled !! input {| ||+1 @@ -13506,7 +17428,7 @@ Tables: 4d. No escaping needed !! end -#### --------------- Links --------------- +#### --------------- Links ---------------- #### 1. Quote marks in link text #### 2. Wikilinks: Escapes needed #### 3. Wikilinks: No escapes needed @@ -13516,9 +17438,9 @@ Tables: 4d. No escaping needed !! test Links 1. Quote marks in link text !! options -disabled +parsoid !! input -[[Foo|<nowiki>Foo''boo''</nowiki>]] +[[Foo|Foo<nowiki>''boo''</nowiki>]] !! result <a rel="mw:WikiLink" href="Foo">Foo''boo''</a> !! end @@ -13526,15 +17448,18 @@ disabled !! test Links 2. WikiLinks: Escapes needed !! options -disabled +parsoid !! input [[Foo|<nowiki>[Foobar]</nowiki>]] [[Foo|<nowiki>Foobar]</nowiki>]] -[[Foo|<nowiki>x [Foobar] x</nowiki>]] +[[Foo|x [Foobar] x]] [[Foo|<nowiki>x [http://google.com g] x</nowiki>]] [[Foo|<nowiki>[[Bar]]</nowiki>]] [[Foo|<nowiki>x [[Bar]] x</nowiki>]] [[Foo|<nowiki>|Bar</nowiki>]] +[[Foo|<nowiki>]]bar</nowiki>]] +[[Foo|<nowiki>[[bar</nowiki>]] +[[Foo|<nowiki>x ]] y [[ z</nowiki>]] !! result <a href="Foo" rel="mw:WikiLink">[Foobar]</a> <a href="Foo" rel="mw:WikiLink">Foobar]</a> @@ -13543,12 +17468,15 @@ disabled <a href="Foo" rel="mw:WikiLink">[[Bar]]</a> <a href="Foo" rel="mw:WikiLink">x [[Bar]] x</a> <a href="Foo" rel="mw:WikiLink">|Bar</a> +<a href="Foo" rel="mw:WikiLink">]]bar</a> +<a href="Foo" rel="mw:WikiLink">[[bar</a> +<a href="Foo" rel="mw:WikiLink">x ]] y [[ z</a> !! end !! test Links 3. WikiLinks: No escapes needed !! options -disabled +parsoid !! input [[Foo|[Foobar]] [[Foo|foo|bar]] @@ -13560,7 +17488,7 @@ disabled !! test Links 4. ExtLinks: Escapes needed !! options -disabled +parsoid !! input [http://google.com <nowiki>[google]</nowiki>] [http://google.com <nowiki>google]</nowiki>] @@ -13572,7 +17500,7 @@ disabled !! test Links 5. ExtLinks: No escapes needed !! options -disabled +parsoid !! input [http://google.com [google] !! result @@ -13583,26 +17511,44 @@ disabled #### 1. Quotes inside <b> and <i> #### 2. Link fragments separated by <i> and <b> tags #### 3. Link fragments inside <i> and <b> +#### 4. No escaping needed #### -------------------------------------- !! test 1. Quotes inside <b> and <i> +!! options +parsoid=html2wt,wt2wt !! input ''<nowiki>'foo'</nowiki>'' ''<nowiki>''foo''</nowiki>'' ''<nowiki>'''foo'''</nowiki>'' +''foo''<nowiki/>'s '''<nowiki>'foo'</nowiki>''' '''<nowiki>''foo''</nowiki>''' '''<nowiki>'''foo'''</nowiki>''' '''<nowiki>foo'</nowiki>''<nowiki>bar'</nowiki>''baz''' +'''foo'''<nowiki/>'s +'''foo'' +''foo''<nowiki/>' +'<nowiki/>''foo''<nowiki/>' +''''foo''' +'''foo'''<nowiki/>' +'<nowiki/>'''foo'''<nowiki/>' !! result <p><i>'foo'</i> <i>''foo''</i> <i>'''foo'''</i> +<i>foo</i>'s <b>'foo'</b> <b>''foo''</b> <b>'''foo'''</b> <b>foo'<i>bar'</i>baz</b> -</p> +<b>foo</b>'s +'<i>foo</i> +<i>foo</i>' +'<i>foo</i>' +'<b>foo</b> +<b>foo</b>' +'<b>foo</b>'</p> !! end !! test @@ -13618,7 +17564,7 @@ disabled !! end !! test -2. Link fragments inside <i> and <b> +3. Link fragments inside <i> and <b> (FIXME: Escaping one or both of [[ and ]] is also acceptable -- this is one of the shortcomings of this format) !! input @@ -13631,7 +17577,18 @@ disabled </p> !! end -#### --------------- Paragraphs --------------- +!! test +4. No escaping needed +!! input +'<span>''bar''</span>' +'<span>'''bar'''</span>' +!! result +<p>'<span><i>bar</i></span>' +'<span><b>bar</b></span>' +</p> +!! end + +#### ----------- Paragraphs --------------- #### 1. No unnecessary escapes #### -------------------------------------- @@ -13644,9 +17601,9 @@ bar <span><nowiki>[[foo]]</nowiki></span> [[bar <span><nowiki>[[foo]]</nowiki></span> -<nowiki>]]bar </nowiki><span><nowiki>[[foo]]</nowiki></span> +]]bar <span><nowiki>[[foo]]</nowiki></span> -<nowiki>=bar </nowiki><span>foo]]</span>= +=bar <span>foo]]</span><nowiki>=</nowiki> !! result <p>bar <span>[[foo]]</span> </p><p>=bar <span>[[foo]]</span> @@ -13656,31 +17613,78 @@ bar <span><nowiki>[[foo]]</nowiki></span> </p> !!end -#### --------------- PRE ------------------ -#### 1. Leading space in SOL context should be escaped -#### -------------------------------------- +#### ----------------------- PRE -------------------------- +#### 1. Leading whitespace in SOL context should be escaped +#### ------------------------------------------------------ !! test -1. Leading space in SOL context should be escaped +1. Leading whitespace in SOL context should be escaped !! options -disabled +parsoid !! input -<nowiki> foo</nowiki> -<!--cmt--><nowiki> foo</nowiki> +<nowiki> </nowiki>a + +<nowiki> </nowiki> a + +<nowiki> </nowiki>a(tab) + +<nowiki> </nowiki> a +<!--cmt--> +<nowiki> </nowiki> a + +a +<nowiki> </nowiki>b + +a +<nowiki> </nowiki>b + +a +<nowiki> </nowiki> b !! result -<p> foo -<!--cmt--> foo -</p> +<p> a</p> +<p> a</p> +<p> a(tab)</p> +<p> a</p> +<p><!--cmt--> a</p> +<p>a + b</p> +<p>a + b</p> +<p>a + b</p> +!! end + +#### --------------- Behavior Switches -------------------- +!! test +1. Valid behavior switches should be escaped +!! options +parsoid=html2wt +!! input +<nowiki>__TOC__</nowiki> +!! result +__TOC__ +!! end + +!! test +2. Invalid behavior switches should not be escaped +!! options +parsoid=html2wt +!! input +__TOO__ +__|__ +!! result +__TOO__ +__|__ !! end #### --------------- HTML tags --------------- #### 1. a tags #### 2. other tags #### 3. multi-line html tag -#### -------------------------------------- +#### ----------------------------------------- !! test 1. a tags !! options -disabled +parsoid !! input <a href="http://google.com">google</a> !! result @@ -13711,6 +17715,15 @@ disabled </p> !! end +!! test +4. extension tags +!! input +<nowiki><ref>foo</ref></nowiki> +!! result +<p><ref>foo</ref> +</p> +!! end + #### --------------- Others --------------- !! test Escaping nowikis @@ -13721,7 +17734,19 @@ Escaping nowikis </p> !! end +## The quote-char in the input is necessary for triggering the bug +!! test +(Bug 52035) Nowiki-escaping should not get tripped by " :" in text +!! options +parsoid=wt2wt,html2wt +!! input +foo's bar : +!! result +<p>foo's bar :</p> +!! end + !! test + Tag-like HTML structures are passed through as text !! input <x y> @@ -13749,16 +17774,14 @@ a>b !! end -# This fails in the PHP parser (see bug 40670, -# https://bugzilla.wikimedia.org/show_bug.cgi?id=40670), so disabled for it. +# This was a bug in the PHP parser (see bug 17663 and its dups, +# https://bugzilla.wikimedia.org/show_bug.cgi?id=17663) !! test Tag names followed by punctuation should not be recognized as tags -!! options -disabled !! input <s.ome> text !! result -<p><s.ome> text +<p><s.ome> text </p> !! end @@ -13841,14 +17864,34 @@ parsoid | style="color:red|Bar |} !! result -<table> +<table><tbody> <tr> <td title="Hello world">Foo </td><td style="color: red">Bar -</td></tr></table> +</td></tr></tbody></table> !! end +!! test +Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353) +!! options +parsoid +!! input +{{}} +!! result +{{}} +!! end + +!! test +Parsoid-only: Don't wrap broken template tags in <nowiki> on wt2wt (Bug 42353) +!! options +parsoid +!! input +}}{{ +!! result +}}{{ +!! end + !!test Accept empty td cell attribute !!input @@ -13915,6 +17958,556 @@ Empty table rows go away !! end +### +### Parsoid-centric tests for testing RTing of inter-element separators +### Edge cases not tested by existing parser tests and specific to +### Parsoid-specific serialization strategies. +### + +!!test +RT-ed inter-element separators should be valid separators +!!input +{| +|- [[foo]] +|} +!!result +<table> + +</table> + +!!end + +!!test +Trailing newlines in a deep dom-subtree that ends a wikitext line should be migrated out +(Parsoid-only since PHP parser relies on Tidy for correct output) +!!options +parsoid +!!input +{| +|<small>foo +bar +|} + +{| +|<small>foo<small> +|} +!!result +!!end + +!!test +Empty TD followed by TD with tpl-generated attribute +!!input +{| +|- +| +|{{echo|style='color:red'}}|foo +|} +!!result +<table> + +<tr> +<td> +</td> +<td>foo +</td></tr></table> + +!!end + +!!test +Indented table with an empty td +!!input + {| + |- + | + |foo + |} +!!result +<table> + +<tr> +<td> +</td> +<td>foo +</td></tr></table> + +!!end + +!!test +Empty TR followed by a template-generated TR +(Parsoid-specific since PHP parser doesn't handle this mixed tbl-wikitext) +!!options +parsoid +!!input +{| +|- +{{echo|<tr><td>foo</td></tr>}} +|} +!!result +<table> +<tbody> +<tr></tr> +<tr about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<tr><td>foo</td></tr>"}},"i":0}}]}'> +<td>foo</td></tr> +</tbody></table> +!!end + +## PHP and parsoid output differ for this, and since this is primarily +## for testing Parsoid's serializer, marking this Parsoid only +!!test +Empty TR followed by mixed-ws-comment line should RT correctly +!!options +parsoid +!!input +{| +|- + <!--c--> +|- +<!--c--> <!--d--> +|} +!!result +<table> +<tbody> +<tr></tr> + <!--c--> +<tr> +<!--c--> </tr><!--d--> +</tbody></table> + +!!end + +!!test +Multi-line image caption generated by templates with/without trailing newlines +!!options +parsoid +!!input +[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}]] +[[File:foo.jpg|thumb|300px|foo\n{{echo|A}}\n{{echo|B}}\n{{echo|C}}\n\n]] +!!result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC</div></div></div> +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Foo.jpg" class="new" title="File:Foo.jpg">File:Foo.jpg</a> <div class="thumbcaption">foo\nA\nB\nC\n\n</div></div></div> + +!!end + +## PHP emits broken html for this, and since this is primarily +## a Parsoid serializer test, marking this Parsoid only +!!test +Improperly nested inline or quotes tags with whitespace in between +!!options +parsoid +!!input +<span> <s>x</span> </s> +''' ''x''' '' +!!result +<p><span> <s>x</s></span><s> </s> +<b> <i>x</i></b><i> </i> +</p> +!!end + +!!test +Encapsulate protected attributes from wt +!!options +parsoid +!!input +<div typeof="mw:placeholder stuff" data-parsoid="weird" data-parsoid-other="no" about="time" rel="mw:true">foo</div> +!!result +<body><div data-x-typeof="mw:placeholder stuff" data-x-data-parsoid="weird" data-x-data-parsoid-other="no" data-x-about="time" data-x-rel="mw:true">foo</div> +</body> +!!end + +## Currently the p-wrapper is fragile in how adds / removes transformations. +## Having nested or stray pre tags results in the attempt to add duplicates, +## causing an assertion fail. This test tries to prevent that situation. +!!test +Ensure ParagraphWrapper can deal with stray closing pre tags +!!options +parsoid=wt2html +!!input +plain text</pre> +!!result +plain text +!!end + +!!test +Ensure fostered text content is wrapped in spans +!!options +parsoid=wt2html +!!input +<table>hi</table><table>ho</table> +!!result +<span>hi</span> +<table></table> +<span>ho</span> +<table></table> +!!end + +!!test +Encapsulation properly handles null DSR information from foster box +!!options +parsoid=wt2html,wt2wt +!!input +{{echo|<table>foo<tr><td>bar</td></tr></table>}} +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" +<table>foo +<tr> +<td>bar</td></tr></table>"}},"i":0}}]}">foo</span> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +1. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table>{{echo|foo<tr><td>bar</td></tr>}}</table> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo +<tr> +<td>bar</td></tr>"}},"i":0}},"</table>"]}">foo</span> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +2. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div>{{echo|foo}}</div><tr><td>bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo"}},"i":0}},"</div> +<tr> +<td>bar</td></tr></table>"]}">foo</div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +3. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div> +<tr> +<td>"}},"i":0}},"bar</td></tr></table>"]}"> +<p>foo</p></div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +4. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><div><p>{{echo|foo</p></div><tr><td>}}bar</td></tr></table> +!!result +<div typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div> +<tr> +<td>"}},"i":0}},"bar</td></tr></table>"]}"> +<p>foo</p></div> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +5. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><tr><td><div><p>{{echo|foo</p></div></td>foo}}</tr></table> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<tr> +<td> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div></td>foo"}},"i":0}},"</tr></table>"]}">foo</span> +<table> +<tbody> +<tr> +<td> +<div> +<p>foo</p></div></td></tr></tbody></table> +!!end + +!!test +6. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table><tr><td><div><p>{{echo|foo</p></div></td>foo</tr></table>}}<p>ok</p> +!!result +<span typeof="mw:Transclusion" data-mw="{"parts":[" +<table> +<tr> +<td> +<div> +<p>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"foo</p></div></td>foo</tr></table>"}},"i":0}}]}">foo</span> +<table> +<tbody> +<tr> +<td> +<div> +<p>foo</p></div></td></tr></tbody></table> +<p>ok</p> +!!end + +!!test +7. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +<table>{{echo|<p>foo</p>}}<td>bar</td></table> +!!result +<p typeof="mw:Transclusion" data-mw="{"parts":[" +<table>",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":" +<p>foo</p>"}},"i":0}}," +<td>bar</td></table>"]}">foo</p> +<table> +<tbody> +<tr> +<td>bar</td></tr></tbody></table> +!!end + +!!test +8. Encapsulate foster-parented transclusion content +!!options +parsoid=wt2wt,wt2html +!!input +{{echo|a +}}{|{{echo|style='color:red'}} +|- +|b +|} +!!result +<p typeof="mw:Transclusion" data-mw="{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a\n"}},"i":0}}]}">a</p><span typeof="mw:Transclusion" data-mw="{"parts":["{|",{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"style":{"wt":"'color:red'"}},"i":0}},"\n|-\n|b\n|}"]}">{{{1}}}</span> +<table> +<tbody> +<tr> +<td>b</td></tr></tbody></table> +!!end + +# ----------------------------------------------------------------- +# The following section of tests are primarily to spec requirements +# around serialization of new/edited content. +# +# All these tests are marked Parsoid html2wt and html2html only +# ---------------------------------------------------------------- + +!! test +Image: Modifying size of an image +!! options +parsoid=html2wt +!! input +[[Image:Wiki.png|230x230px]] +!! result +<p data-parsoid='{"dsr":[0,24,0,0]}'><span typeof="mw:Image" data-parsoid='{"optList":[{"ck":"width","ak":"100px"}],"cacheKey":"[[Image:Wiki.png|100px]]","img":{"h":115,"w":100,"wdset":true},"dsr":[0,24,null,null]}'><a href="./File:Wiki.png" data-parsoid='{"a":{"href":"./File:Wiki.png"}}'><img resource="./File:Wiki.png" src="//upload.wikimedia.org/wikipedia/en/thumb/b/bc/Wiki.png/100px-Wiki.png" height="230" width="200" data-parsoid='{"a":{"resource":"./File:Wiki.png"},"sa":{"resource":"Image:Wiki.png"}}'></a></span></p> +!!end + +!! test +Image: New block level image should have \n before and after +!! options +parsoid=html2wt +!! input +123 +[[File:Wiki.png|right|thumb|150x150px]] +456 +!! result +<p>123</p><figure typeof="mw:Image/Thumb" class="mw-halign-right"><a href="./File:Wiki.png"><img src="http://192.168.142.128/mw/images/thumb/b/bc/Wiki.png/131px-Wiki.png" width="131" height="150" resource="./File:Wiki.png"></a></figure><p>456</p> +!!end + +# Wacky -- the leading newline in input is required because +# that is what the serializer emits. To be fixed. Not fixing +# the test because this test is required to test serialization of +# new content and preferred whitespace style. +!! test +Lists: Serialize correctly even when list content is wrapped in p-tags (like VE does) +!! options +parsoid=html2wt +!! input + +* foo +!! result +<ul> +<li><p>foo</p></li> +</ul> +!! end + +# Wacky -- the leading newline in input is required because +# that is what the serializer emits. To be fixed. Not fixing +# the test because this test is required to test serialization of +# new content and preferred whitespace style. +!! test +Lists: Add space after bullets +!! options +parsoid=html2wt +!! input + +* foo +* bar +* <span> baz</span> +!! result +<ul> +<li>foo</li> +<li> bar</li> +<li><span> baz</span></li> +</ul> +!! end + +!! test +Parsoid: Serialize positional parameters with = in them as named parameter +!! options +parsoid=html2wt +!! input +{{echo|1 = f=oo}} + +{{echo|1 = f=oo|2 = bar}} + +<!--Orig params with data-parsoid has heuristics for handling = chars--> +<!--FIXME: But maybe the heuristic needs fixing to apply to new params as well--> +{{echo|<nowiki>f=oo</nowiki>|bar}} +!! result +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"}},"i":0}}]}'>foo</p> + +<p about="#mwt1" typeof="mw:Transclusion" +data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"}, "2":{"wt":"bar"}},"i":0}}]}'>foo</p> + +<!--Orig params with data-parsoid has heuristics for handling = chars--> +<!--FIXME: But maybe the heuristic needs fixing to apply to new params as well--> +<p data-parsoid='{"pi":[[{"k":"1","spc":["","","",""]},{"k":"2","spc":["","","",""]}]]}' about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"f=oo"},"2":{"wt":"bar"}},"i":0}}]}'>foo</p> +!! end + +!! test +Parsoid: Correctly serialize block-node children when they are a combination of text and p-nodes +!! options +parsoid=html2wt +!! input +<div>a +b +</div> +<div>a +b +</div> +<div> +a + +b +</div> +!! result +<div>a<p>b</p></div> +<div>a +<p>b</p></div> +<div> +a +<p>b</p></div> +!! end + +#----------------------------- +# I/B quote minimization tests +#----------------------------- + +!! test +1. I/B quote minimization: wikitext-only tags should be combined +!! options +parsoid=html2wt +!! input +''AB'' + +'''AB''' + +''A'''B''''' + +'''A''B''''' + +'''A''BC''D''' + +'''''AB''''' + +'''''AB''''' + +'''''AB''''' +!! result +<p><i>A</i><i>B</i></p> +<p><b>A</b><b>B</b></p> +<p><i>A</i><b><i>B</i></b></p> +<p><b>A</b><i><b>B</b></i></p> +<p><b>A</b><i><b>B</b><b>C</b></i><b>D</b></p> +<p><i><b>A</b></i><i><b>B</b></i></p> +<p><i><b>A</b></i><b><i>B</i></b></p> +<p><b><i>A</i></b><i><b>B</b></i></p> +!! end + +!! test +2. I/B quote minimization: wikitext and html tags should not be combined +!! options +parsoid=html2wt +!! input +''A''<i>B</i> + +''A'''''<i>B</i>''' +!! result +<p><i>A</i><i data-parsoid='{"stx":"html"}'>B</i></p> +<p><i>A</i><b><i data-parsoid='{"stx":"html"}'>B</i></b></p> +!! end + +!! test +3. I/B quote minimization: templated content stops minimization +!! options +parsoid=html2wt +!! input +''A''{{echo|''B''}} + +''A''{{echo|'''''B'''''}} +!! result +<p><i>A</i><i about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"''B''"}},"i":0}}]}'>B</i> +<p><i>A</i><b about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"'''''B'''''"}},"i":0}}]}'><i>B</i></b> +!! end + +!! test +4. I/B quote minimization: new content should be mimimized with adjacent old content +!! options +parsoid=html2wt +!! input +''AB'' + +'''AB''' + +''A'''B''''' +!! result +<p><i>A</i><i data-parsoid='{}'>B</i></p> +<p><b data-parsoid='{}'>A</b><b>B</b></p> +<p><i>A</i><b data-parsoid='{}'><i data-parsoid='{}'>B</i></b></p> +!! end + +# ----------------------------------------------------------------- +# End of section for Parsoid-only html2wt tests for serialization +# of new content +# ----------------------------------------------------------------- + TODO: more images more tables diff --git a/tests/parser/preprocess/All_system_messages.expected b/tests/parser/preprocess/All_system_messages.expected index 897c5fb0..078d8f0d 100644 --- a/tests/parser/preprocess/All_system_messages.expected +++ b/tests/parser/preprocess/All_system_messages.expected @@ -1239,27 +1239,6 @@ diff </td><td> <template lineStart="1"><title>int:Difference</title></template> </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> -<template lineStart="1"><title>int:Disambiguations</title></template> -</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> -<template lineStart="1"><title>int:Disambiguationspage</title></template> -</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> -<template lineStart="1"><title>int:Disambiguationstext</title></template> -</td></tr><tr><td> [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]<br> [[MediaWiki_talk:Disclaimerpage|Talk]] </td><td> diff --git a/tests/parser/preprocess/All_system_messages.txt b/tests/parser/preprocess/All_system_messages.txt index fc10d7cf..3c30da94 100644 --- a/tests/parser/preprocess/All_system_messages.txt +++ b/tests/parser/preprocess/All_system_messages.txt @@ -1239,27 +1239,6 @@ diff </td><td> {{int:Difference}} </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> -{{int:Disambiguations}} -</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> -{{int:Disambiguationspage}} -</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 <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. -</td><td> -{{int:Disambiguationstext}} -</td></tr><tr><td> [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Disclaimerpage&action=edit disclaimerpage]<br> [[MediaWiki_talk:Disclaimerpage|Talk]] </td><td> diff --git a/tests/parserTests.php b/tests/parserTests.php index 804a30cb..debb3575 100644 --- a/tests/parserTests.php +++ b/tests/parserTests.php @@ -27,8 +27,8 @@ $otions = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled', 'run-parsoid' ); $optionsWithArgs = array( 'regex', 'filter', 'seed', 'setversion' ); -require_once( __DIR__ . '/../maintenance/commandLine.inc' ); -require_once( __DIR__ . '/TestsAutoLoader.php' ); +require_once __DIR__ . '/../maintenance/commandLine.inc'; +require_once __DIR__ . '/TestsAutoLoader.php'; if ( isset( $options['help'] ) ) { echo <<<ENDS @@ -84,11 +84,11 @@ if ( isset( $options['file'] ) ) { # Print out software version to assist with locating regressions $version = SpecialVersion::getVersion(); -echo( "This is MediaWiki version {$version}.\n\n" ); +echo "This is MediaWiki version {$version}.\n\n"; if ( isset( $options['fuzz'] ) ) { $tester->fuzzTest( $files ); } else { $ok = $tester->runTestsFromFiles( $files ); - exit ( $ok ? 0 : 1 ); + exit( $ok ? 0 : 1 ); } diff --git a/tests/phpunit/MediaWikiLangTestCase.php b/tests/phpunit/MediaWikiLangTestCase.php index 0cf6e383..1131385f 100644 --- a/tests/phpunit/MediaWikiLangTestCase.php +++ b/tests/phpunit/MediaWikiLangTestCase.php @@ -15,6 +15,10 @@ abstract class MediaWikiLangTestCase extends MediaWikiTestCase { "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")" ); } + // HACK: Call getLanguage() so the real $wgContLang is cached as the user language + // rather than our fake one. This is to avoid breaking other, unrelated tests. + RequestContext::getMain()->getLanguage(); + $langCode = 'en'; # For mainpage to be 'Main Page' $langObj = Language::factory( $langCode ); diff --git a/tests/phpunit/MediaWikiPHPUnitCommand.php b/tests/phpunit/MediaWikiPHPUnitCommand.php index 12c2e003..042956a9 100644 --- a/tests/phpunit/MediaWikiPHPUnitCommand.php +++ b/tests/phpunit/MediaWikiPHPUnitCommand.php @@ -12,13 +12,29 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { 'use-normal-tables' => false, 'reuse-db' => false, 'wiki=' => false, + 'debug-tests' => false, ); public function __construct() { foreach ( self::$additionalOptions as $option => $default ) { $this->longOptions[$option] = $option . 'Handler'; } + } + + protected function handleArguments( array $argv ) { + parent::handleArguments( $argv ); + + if ( !isset( $this->arguments['listeners'] ) ) { + $this->arguments['listeners'] = array(); + } + foreach ( $this->options[0] as $option ) { + switch ( $option[0] ) { + case '--debug-tests': + $this->arguments['listeners'][] = new MediaWikiPHPUnitTestListener( 'PHPUnitCommand' ); + break; + } + } } public static function main( $exit = true ) { @@ -86,7 +102,7 @@ class MediaWikiPHPUnitCommand extends PHPUnit_TextUI_Command { ParserTest-specific options: --regex="<regex>" Only run parser tests that match the given regex - --file="<filename>" Prints the version and exits. + --file="<filename>" File describing parser tests --keep-uploads Re-use the same upload directory for each test, don't delete it @@ -95,7 +111,9 @@ Database options: --reuse-db Init DB only if tables are missing and keep after finish. +Debugging options: + --debug-tests Log testing activity to the PHPUnitCommand log channel. + EOT; } - } diff --git a/tests/phpunit/MediaWikiPHPUnitTestListener.php b/tests/phpunit/MediaWikiPHPUnitTestListener.php new file mode 100644 index 00000000..7237ef32 --- /dev/null +++ b/tests/phpunit/MediaWikiPHPUnitTestListener.php @@ -0,0 +1,114 @@ +<?php +class MediaWikiPHPUnitTestListener implements PHPUnit_Framework_TestListener { + + /** + * @var string + */ + protected $logChannel; + + public function __construct( $logChannel ) { + $this->logChannel = $logChannel; + } + + protected function getTestName( PHPUnit_Framework_Test $test ) { + $name = get_class( $test ); + + if ( $test instanceof PHPUnit_Framework_TestCase ) { + $name .= '::' . $test->getName( true ); + } + + return $name; + } + + protected function getErrorName( Exception $exception ) { + $name = get_class( $exception ); + $name = "[$name] " . $exception->getMessage(); + + return $name; + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'ERROR in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure( PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time ) { + wfDebugLog( $this->logChannel, 'FAILURE in ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Incomplete test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest( PHPUnit_Framework_Test $test, Exception $e, $time ) { + wfDebugLog( $this->logChannel, 'Skipped test ' . $this->getTestName( $test ) . ': ' . $this->getErrorName( $e ) ); + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'START suite ' . $suite->getName() ); + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite( PHPUnit_Framework_TestSuite $suite ) { + wfDebugLog( $this->logChannel, 'END suite ' . $suite->getName() ); + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest( PHPUnit_Framework_Test $test ) { + wfDebugLog( $this->logChannel, 'Start test ' . $this->getTestName( $test ) ); + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest( PHPUnit_Framework_Test $test, $time ) { + wfDebugLog( $this->logChannel, 'End test ' . $this->getTestName( $test ) ); + } +} diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 7e6e0ab8..6ce78b56 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -64,7 +64,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'oracle' ); - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->backupGlobals = false; @@ -137,6 +137,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { protected function getNewTempFile() { $fname = tempnam( wfTempDir(), 'MW_PHPUnit_' . get_class( $this ) . '_' ); $this->tmpfiles[] = $fname; + return $fname; } @@ -158,6 +159,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { // where temporary directory creation is bundled and can be improved unlink( $fname ); $this->assertTrue( wfMkdirParents( $fname ) ); + return $fname; } @@ -171,7 +173,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->called['setUp'] = 1; /* - //@todo: global variables to restore for *every* test + // @todo global variables to restore for *every* test array( 'wgLang', 'wgContLang', @@ -348,7 +350,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * Stub. If a test needs to add additional data to the database, it should * implement this method and do so */ - function addDBData() {} + function addDBData() { + } private function addCoreDBData() { # disabled for performance @@ -377,7 +380,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { 'page_touched' => $this->db->timestamp(), 'page_latest' => 0, 'page_len' => 0 ), __METHOD__, array( 'IGNORE' ) ); - } User::resetIdByNameCache(); @@ -394,7 +396,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $user->saveSettings(); } - //Make 1 page with 1 revision $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); if ( !$page->getId() == 0 ) { @@ -438,7 +439,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * even if using different parameters. * * @param DatabaseBase $db The database connection - * @param String $prefix The prefix to use for the new table set (aka schema). + * @param String $prefix The prefix to use for the new table set (aka schema). * * @throws MWException if the database table prefix is already $prefix */ @@ -461,6 +462,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( ( $db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) { CloneDatabase::changePrefix( $prefix ); + return; } else { $dbClone->cloneTableStructure(); @@ -523,6 +525,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { private static function unprefixTable( $tableName ) { global $wgDBprefix; + return substr( $tableName, strlen( $wgDBprefix ) ); } @@ -534,6 +537,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { global $wgDBprefix; $tables = $db->listTables( $wgDBprefix, __METHOD__ ); + + if ( $db->getType() === 'mysql' ) { + # bug 43571: cannot clone VIEWs under MySQL + $views = $db->listViews( $wgDBprefix, __METHOD__ ); + $tables = array_diff( $tables, $views ); + } $tables = array_map( array( __CLASS__, 'unprefixTable' ), $tables ); // Don't duplicate test tables from the previous fataled run @@ -547,6 +556,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { unset( $tables['searchindex_segments'] ); $tables = array_flip( $tables ); } + return $tables; } @@ -561,13 +571,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( isset( MediaWikiPHPUnitCommand::$additionalOptions[$offset] ) ) { return MediaWikiPHPUnitCommand::$additionalOptions[$offset]; } - } public function setCliArg( $offset, $value ) { MediaWikiPHPUnitCommand::$additionalOptions[$offset] = $value; - } /** @@ -775,7 +783,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } /** - * Returns true iff the given namespace defaults to Wikitext + * Returns true if the given namespace defaults to Wikitext * according to $wgNamespaceContentModels * * @param int $ns The namespace ID to check @@ -839,12 +847,13 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { ) { $wikitextNS = $ns; + return $wikitextNS; } } // give up - // @todo: Inside a test, we could skip the test as incomplete. + // @todo Inside a test, we could skip the test as incomplete. // But frequently, this is used in fixture setup. throw new MWException( "No namespace defaults to wikitext!" ); } @@ -906,6 +915,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { if ( !$loaded ) { $this->markTestSkipped( "PHP extension '$extName' is not loaded, skipping." ); } + return $loaded; } @@ -914,6 +924,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { * the provided code. * * @since 1.21 + * @deprecated since 1.22 Use setExpectedException * * @param callable $code * @param string $expected @@ -934,5 +945,4 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $this->assertInstanceOf( $expected, $pokemons, $message ); } - } diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 01caf8f4..d929b79d 100644 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -11,22 +11,5 @@ if ( !defined( 'MW_PHPUNIT_TEST' ) ) { You are running these tests directly from phpunit. You may not have all globals correctly set. Running phpunit.php instead is recommended. EOF; - require_once ( __DIR__ . "/phpunit.php" ); + require_once __DIR__ . "/phpunit.php"; } - -// Output a notice when running with older versions of PHPUnit -if ( version_compare( PHPUnit_Runner_Version::id(), "3.6.7", "<" ) ) { - echo <<<EOF -******************************************************************************** - -These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may -show failures because earlier versions of PHPUnit do not properly implement -dependencies. - -******************************************************************************** - -EOF; -} - -/** @todo Check if this is really needed */ -MessageCache::destroyInstance(); diff --git a/tests/phpunit/data/db/sqlite/tables-1.16.sql b/tests/phpunit/data/db/sqlite/tables-1.16.sql index 6e56add2..7e8f30ec 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.16.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.16.sql @@ -146,11 +146,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.17.sql b/tests/phpunit/data/db/sqlite/tables-1.17.sql index 69ae3764..e02e3e14 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.17.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.17.sql @@ -151,11 +151,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/db/sqlite/tables-1.18.sql b/tests/phpunit/data/db/sqlite/tables-1.18.sql index b106d2b7..8bfc28e2 100644 --- a/tests/phpunit/data/db/sqlite/tables-1.18.sql +++ b/tests/phpunit/data/db/sqlite/tables-1.18.sql @@ -157,11 +157,6 @@ CREATE TABLE /*_*/externallinks ( CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from, el_to(40)); CREATE INDEX /*i*/el_to ON /*_*/externallinks (el_to(60), el_from); CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index(60)); -CREATE TABLE /*_*/external_user ( - eu_local_id int unsigned NOT NULL PRIMARY KEY, - eu_external_id varchar(255) binary NOT NULL -) /*$wgDBTableOptions*/; -CREATE UNIQUE INDEX /*i*/eu_external_id ON /*_*/external_user (eu_external_id); CREATE TABLE /*_*/langlinks ( ll_from int unsigned NOT NULL default 0, ll_lang varbinary(20) NOT NULL default '', diff --git a/tests/phpunit/data/less/common/test.common.mixins.less b/tests/phpunit/data/less/common/test.common.mixins.less new file mode 100644 index 00000000..2fbe9b79 --- /dev/null +++ b/tests/phpunit/data/less/common/test.common.mixins.less @@ -0,0 +1,5 @@ +.test-mixin (@value) { + color: @value; + border: @foo solid @Foo; + line-height: test-sum(@bar, 10, 20); +} diff --git a/tests/phpunit/data/less/module/dependency.less b/tests/phpunit/data/less/module/dependency.less new file mode 100644 index 00000000..c7725a25 --- /dev/null +++ b/tests/phpunit/data/less/module/dependency.less @@ -0,0 +1,3 @@ +@import "test.common.mixins"; + +@unitTestColor: green; diff --git a/tests/phpunit/data/less/module/styles.css b/tests/phpunit/data/less/module/styles.css new file mode 100644 index 00000000..b78780a9 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.css @@ -0,0 +1,6 @@ +/* @noflip */ +.unit-tests { + color: green; + border: 2px solid #eeeeee; + line-height: 35; +} diff --git a/tests/phpunit/data/less/module/styles.less b/tests/phpunit/data/less/module/styles.less new file mode 100644 index 00000000..ecac8392 --- /dev/null +++ b/tests/phpunit/data/less/module/styles.less @@ -0,0 +1,6 @@ +@import "dependency"; + +/* @noflip */ +.unit-tests { + .test-mixin(@unitTestColor); +} diff --git a/tests/phpunit/data/xmp/7.result.php b/tests/phpunit/data/xmp/7.result.php index 9aa867bc..115cdc92 100644 --- a/tests/phpunit/data/xmp/7.result.php +++ b/tests/phpunit/data/xmp/7.result.php @@ -1,26 +1,26 @@ <?php -$result = array ( +$result = array( 'xmp-exif' => - array ( + array( 'CameraOwnerName' => 'Me!', ), 'xmp-general' => - array ( + array( 'LicenseUrl' => 'http://creativecommons.com/cc-by-2.9', 'ImageDescription' => - array ( + array( 'x-default' => 'Test image for the cc: xmp: xmpRights: namespaces in xmp', '_type' => 'lang', ), 'ObjectName' => - array ( + 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 ( + array( 0 => 'http://example.com/identifierurl', 1 => 'urn:sha1:342524abcdef', '_type' => 'ul', @@ -33,12 +33,12 @@ $result = array ( 'RightsCertificate' => 'http://example.com/rights-certificate/', 'Copyrighted' => 'True', 'CopyrightOwner' => - array ( + array( 0 => 'Bawolff is copyright owner', '_type' => 'ul', ), 'UsageTerms' => - array ( + array( 'x-default' => 'do whatever you want', 'en-gb' => 'Do whatever you want in british english', '_type' => 'lang', @@ -46,7 +46,7 @@ $result = array ( 'WebStatement' => 'http://example.com/web_statement', ), 'xmp-deprecated' => - array ( + array( 'Identifier' => 'http://example.com/identifierurl/wrong', ), ); diff --git a/tests/phpunit/includes/ArticleTablesTest.php b/tests/phpunit/includes/ArticleTablesTest.php index 967ffa17..0f159ae4 100644 --- a/tests/phpunit/includes/ArticleTablesTest.php +++ b/tests/phpunit/includes/ArticleTablesTest.php @@ -5,7 +5,7 @@ */ class ArticleTablesTest extends MediaWikiLangTestCase { - function testbug14404() { + public function testbug14404() { global $wgContLang, $wgLanguageCode, $wgLang; $title = Title::newFromText( 'Bug 14404' ); @@ -16,18 +16,17 @@ class ArticleTablesTest extends MediaWikiLangTestCase { $wgContLang = Language::factory( 'es' ); $wgLang = Language::factory( 'fr' ); - $status = $page->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', 0, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{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->doEditContent( new WikitextContent( '{{:{{int:history}}}}' ), 'Test code for bug 14404', EDIT_UPDATE, false, $user ); + $page->doEditContent( new WikitextContent( '{{:{{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 index 867c4f00..b4d6dca6 100644 --- a/tests/phpunit/includes/ArticleTest.php +++ b/tests/phpunit/includes/ArticleTest.php @@ -25,14 +25,14 @@ class ArticleTest extends MediaWikiTestCase { $this->article = null; } - function testImplementsGetMagic() { + public function testImplementsGetMagic() { $this->assertEquals( false, $this->article->mLatest, "Article __get magic" ); } /** * @depends testImplementsGetMagic */ - function testImplementsSetMagic() { + public function testImplementsSetMagic() { $this->article->mLatest = 2; $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" ); } @@ -40,13 +40,13 @@ class ArticleTest extends MediaWikiTestCase { /** * @depends testImplementsSetMagic */ - function testImplementsCallMagic() { + public function testImplementsCallMagic() { $this->article->mLatest = 33; $this->article->mDataLoaded = true; $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" ); } - function testGetOrSetOnNewProperty() { + public function testGetOrSetOnNewProperty() { $this->article->ext_someNewProperty = 12; $this->assertEquals( 12, $this->article->ext_someNewProperty, "Article get/set magic on new field" ); @@ -59,7 +59,7 @@ class ArticleTest extends MediaWikiTestCase { /** * Checks for the existence of the backwards compatibility static functions (forwarders to WikiPage class) */ - function testStaticFunctions() { + public function testStaticFunctions() { $this->hideDeprecated( 'Article::getAutosummary' ); $this->hideDeprecated( 'WikiPage::getAutosummary' ); $this->hideDeprecated( 'CategoryPage::getAutosummary' ); // Inherited from Article @@ -76,7 +76,7 @@ class ArticleTest extends MediaWikiTestCase { "Article static functions" ); } - function testWikiPageFactory() { + public function testWikiPageFactory() { $title = Title::makeTitle( NS_FILE, 'Someimage.png' ); $page = WikiPage::factory( $title ); $this->assertEquals( 'WikiFilePage', get_class( $page ) ); diff --git a/tests/phpunit/includes/BlockTest.php b/tests/phpunit/includes/BlockTest.php index 19c9b687..21de0985 100644 --- a/tests/phpunit/includes/BlockTest.php +++ b/tests/phpunit/includes/BlockTest.php @@ -51,36 +51,36 @@ class BlockTest extends MediaWikiLangTestCase { } else { throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" ); } + + $this->addXffBlocks(); } /** * debug function : dump the ipblocks table */ function dumpBlocks() { - $v = $this->db->query( 'SELECT * FROM unittest_ipblocks' ); + $v = $this->db->select( 'ipblocks', '*' ); print "Got " . $v->numRows() . " rows. Full dump follow:\n"; foreach ( $v as $row ) { print_r( $row ); } } - function testInitializerFunctionsReturnCorrectBlock() { + public 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() { + public 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()" ); - } /** @@ -91,7 +91,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116LoadWithEmptyIp( $vagueTarget ) { + public function testBug29116LoadWithEmptyIp( $vagueTarget ) { $this->hideDeprecated( 'Block::load' ); $uid = User::idFromName( 'UTBlockee' ); @@ -111,7 +111,7 @@ class BlockTest extends MediaWikiLangTestCase { * * @dataProvider provideBug29116Data */ - function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) { + public 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 ) ); } @@ -124,14 +124,13 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testBlockedUserCanNotCreateAccount() { + public function testBlockedUserCanNotCreateAccount() { $username = 'BlockedUserToCreateAccountWith'; $u = User::newFromName( $username ); $u->setPassword( 'NotRandomPass' ); $u->addToDatabase(); unset( $u ); - // Sanity check $this->assertNull( Block::newFromTarget( $username ), @@ -185,7 +184,7 @@ class BlockTest extends MediaWikiLangTestCase { ); } - function testCrappyCrossWikiBlocks() { + public function testCrappyCrossWikiBlocks() { // Delete the last round's block if it's still there $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' ); if ( $oldBlock ) { @@ -228,4 +227,128 @@ class BlockTest extends MediaWikiLangTestCase { $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' ); $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' ); } + + protected function addXffBlocks() { + static $inited = false; + + if ( $inited ) { + return; + } + + $inited = true; + + $blockList = array( + array( 'target' => '70.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '2001:4860:4001::/48', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range6 Hardblock', + 'ACDisable' => false, + 'isHardblock' => true, + 'isAutoBlocking' => false, + ), + array( 'target' => '60.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock with AC Disabled', + 'ACDisable' => true, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.2.0.0/16', + 'type' => Block::TYPE_RANGE, + 'desc' => 'Range Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + array( 'target' => '50.1.1.1', + 'type' => Block::TYPE_IP, + 'desc' => 'Exact Softblock', + 'ACDisable' => false, + 'isHardblock' => false, + 'isAutoBlocking' => false, + ), + ); + + foreach ( $blockList as $insBlock ) { + $target = $insBlock['target']; + + if ( $insBlock['type'] === Block::TYPE_IP ) { + $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName(); + } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) { + $target = IP::sanitizeRange( $target ); + } + + $block = new Block(); + $block->setTarget( $target ); + $block->setBlocker( 'testblocker@global' ); + $block->mReason = $insBlock['desc']; + $block->mExpiry = 'infinity'; + $block->prevents( 'createaccount', $insBlock['ACDisable'] ); + $block->isHardblock( $insBlock['isHardblock'] ); + $block->isAutoblocking( $insBlock['isAutoBlocking'] ); + $block->insert(); + } + } + + public static function providerXff() { + return array( + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5', + 'count' => 3, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Hardblock' + ), + array( 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5', + 'count' => 2, + 'result' => 'Exact Softblock' + ), + array( 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT\>, 60.2.1.1, 2.3.4.5', + 'count' => 1, + 'result' => 'Range Softblock with AC Disabled' + ), + array( 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5', + 'count' => 2, + 'result' => 'Range6 Hardblock' + ), + ); + } + + /** + * @dataProvider providerXff + */ + public function testBlocksOnXff( $xff, $exCount, $exResult ) { + $list = array_map( 'trim', explode( ',', $xff ) ); + $xffblocks = Block::getBlocksForIPList( $list, true ); + $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff ); + $block = Block::chooseBlock( $xffblocks, $list ); + $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff ); + } } diff --git a/tests/phpunit/includes/CdbTest.php b/tests/phpunit/includes/CdbTest.php index add585d7..e3d9da7c 100644 --- a/tests/phpunit/includes/CdbTest.php +++ b/tests/phpunit/includes/CdbTest.php @@ -66,7 +66,6 @@ class CdbTest extends MediaWikiTestCase { $this->cdbAssert( "PHP error", $key, $v1, $value ); $this->cdbAssert( "DBA error", $key, $v2, $value ); } - } private function randomString() { @@ -75,6 +74,7 @@ class CdbTest extends MediaWikiTestCase { for ( $j = 0; $j < $len; $j++ ) { $s .= chr( mt_rand( 0, 255 ) ); } + return $s; } diff --git a/tests/phpunit/includes/CollationTest.php b/tests/phpunit/includes/CollationTest.php index c746208b..43bb3941 100644 --- a/tests/phpunit/includes/CollationTest.php +++ b/tests/phpunit/includes/CollationTest.php @@ -20,7 +20,7 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider prefixDataProvider */ - function testIsPrefix( $lang, $base, $extended ) { + public function testIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -47,12 +47,13 @@ class CollationTest extends MediaWikiLangTestCase { array( 'en', 'A', 'Aꦲ' ), ); } + /** * Opposite of testIsPrefix * * @dataProvider notPrefixDataProvider */ - function testNotIsPrefix( $lang, $base, $extended ) { + public function testNotIsPrefix( $lang, $base, $extended ) { $cp = Collator::create( $lang ); $cp->setStrength( Collator::PRIMARY ); $baseBin = $cp->getSortKey( $base ); @@ -80,10 +81,11 @@ class CollationTest extends MediaWikiLangTestCase { * * @dataProvider firstLetterProvider */ - function testGetFirstLetter( $collation, $string, $firstLetter ) { + public function testGetFirstLetter( $collation, $string, $firstLetter ) { $col = Collation::factory( $collation ); $this->assertEquals( $firstLetter, $col->getFirstLetter( $string ) ); } + function firstLetterProvider() { return array( array( 'uppercase', 'Abc', 'A' ), diff --git a/tests/phpunit/includes/DiffHistoryBlobTest.php b/tests/phpunit/includes/DiffHistoryBlobTest.php index dcd9dddf..a4d5b91a 100644 --- a/tests/phpunit/includes/DiffHistoryBlobTest.php +++ b/tests/phpunit/includes/DiffHistoryBlobTest.php @@ -4,14 +4,17 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { protected function setUp() { if ( !extension_loaded( 'xdiff' ) ) { $this->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' ); + if ( !extension_loaded( 'hash' ) ) { + $this->markTestSkipped( 'The hash extension is not available' ); + return; } parent::setUp(); @@ -21,7 +24,7 @@ class DiffHistoryBlobTest extends MediaWikiTestCase { * Test for DiffHistoryBlob::xdiffAdler32() * @dataProvider provideXdiffAdler32 */ - function testXdiffAdler32( $input ) { + public function testXdiffAdler32( $input ) { $xdiffHash = substr( xdiff_string_rabdiff( $input, '' ), 0, 4 ); $dhb = new DiffHistoryBlob; $myHash = $dhb->xdiffAdler32( $input ); diff --git a/tests/phpunit/includes/EditPageTest.php b/tests/phpunit/includes/EditPageTest.php index 00eba30a..87272a4c 100644 --- a/tests/phpunit/includes/EditPageTest.php +++ b/tests/phpunit/includes/EditPageTest.php @@ -9,12 +9,12 @@ * @group medium * ^--- tell phpunit that these test cases may take longer than 2 seconds. */ -class EditPageTest extends MediaWikiTestCase { +class EditPageTest extends MediaWikiLangTestCase { /** * @dataProvider provideExtractSectionTitle */ - function testExtractSectionTitle( $section, $title ) { + public function testExtractSectionTitle( $section, $title ) { $extracted = EditPage::extractSectionTitle( $section ); $this->assertEquals( $title, $extracted ); } @@ -173,15 +173,90 @@ class EditPageTest extends MediaWikiTestCase { } public function testCreatePage() { - $text = "Hello World!"; - $edit = array( - 'wpTextbox1' => $text, - 'wpSummary' => 'just testing', + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "Hello World!", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Hello World!", + "expected article being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'EditPageTest_testCreatePage', + null, + null, + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected article not being created if empty" + ); + + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "Not January", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "Not January", + "expected MediaWiki: page being created" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:EditPageTest_testCreatePage', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected not-registered MediaWiki: page not being created if empty" ); - $this->assertEdit( 'EditPageTest_testCreatePafe', null, null, $edit, - EditPage::AS_SUCCESS_NEW_ARTICLE, $text, - "expected successfull creation with given text" ); + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_SUCCESS_NEW_ARTICLE, + "", + "expected registered MediaWiki: page being created even if empty" + )->doDeleteArticleReal( 'EditPageTest_testCreatePage' ); + + $this->assertEdit( + 'MediaWiki:Ipb-default-expiry', + null, + 'UTSysop', + array( + 'wpTextbox1' => "", + ), + EditPage::AS_BLANK_ARTICLE, + "", + "expected registered MediaWiki: page whose default content is empty not being created if empty" + ); + + $this->assertEdit( + 'MediaWiki:January', + null, + 'UTSysop', + array( + 'wpTextbox1' => "January", + ), + EditPage::AS_BLANK_ARTICLE, + null, + "expected MediaWiki: page not being created if text equals default message" + ); } public function testUpdatePage() { diff --git a/tests/phpunit/includes/ExternalStoreTest.php b/tests/phpunit/includes/ExternalStoreTest.php index 99544e7e..fcffcbc2 100644 --- a/tests/phpunit/includes/ExternalStoreTest.php +++ b/tests/phpunit/includes/ExternalStoreTest.php @@ -5,7 +5,7 @@ class ExternalStoreTest extends MediaWikiTestCase { - function testExternalFetchFromURL() { + public function testExternalFetchFromURL() { $this->setMwGlobals( 'wgExternalStores', false ); $this->assertFalse( diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php index 067cfc4a..6c67beb1 100644 --- a/tests/phpunit/includes/ExtraParserTest.php +++ b/tests/phpunit/includes/ExtraParserTest.php @@ -27,7 +27,7 @@ class ExtraParserTest extends MediaWikiTestCase { } // Bug 8689 - Long numeric lines kill the parser - function testBug8689() { + public function testBug8689() { global $wgUser; $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; @@ -38,13 +38,13 @@ class ExtraParserTest extends MediaWikiTestCase { } /* Test the parser entry points */ - function testParse() { + public function testParse() { $title = Title::newFromText( __FUNCTION__ ); $parserOutput = $this->parser->parse( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); $this->assertEquals( "<p>Test\nContent of <i>Template:Foo</i>\nContent of <i>Template:Bar</i>\n</p>", $parserOutput->getText() ); } - function testPreSaveTransform() { + public function testPreSaveTransform() { global $wgUser; $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preSaveTransform( "Test\r\n{{subst:Foo}}\n{{Bar}}", $title, $wgUser, $this->options ); @@ -52,7 +52,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "Test\nContent of ''Template:Foo''\n{{Bar}}", $outputText ); } - function testPreprocess() { + public function testPreprocess() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->preprocess( "Test\n{{Foo}}\n{{Bar}}", $title, $this->options ); @@ -62,7 +62,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() makes all templates substs and removes tildes */ - function testCleanSig() { + public function testCleanSig() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -72,9 +72,8 @@ class ExtraParserTest extends MediaWikiTestCase { /** * cleanSig() should do nothing if disabled */ - function testCleanSigDisabled() { - global $wgCleanSignatures; - $wgCleanSignatures = false; + public function testCleanSigDisabled() { + $this->setMwGlobals( 'wgCleanSignatures', false ); $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->cleanSig( "{{Foo}} ~~~~" ); @@ -86,7 +85,7 @@ class ExtraParserTest extends MediaWikiTestCase { * cleanSigInSig() just removes tildes * @dataProvider provideStringsForCleanSigInSig */ - function testCleanSigInSig( $in, $out ) { + public function testCleanSigInSig( $in, $out ) { $this->assertEquals( Parser::cleanSigInSig( $in ), $out ); } @@ -98,7 +97,7 @@ class ExtraParserTest extends MediaWikiTestCase { ); } - function testGetSection() { + public 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 ); @@ -106,7 +105,7 @@ class ExtraParserTest extends MediaWikiTestCase { $this->assertEquals( "== Heading 1 ==\nSection 1\n=== Heading 2 ===\nSection 2", $outputText1 ); } - function testReplaceSection() { + public 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 ); @@ -115,7 +114,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * Templates and comments are not affected, but noinclude/onlyinclude is. */ - function testGetPreloadText() { + public function testGetPreloadText() { $title = Title::newFromText( __FUNCTION__ ); $outputText = $this->parser->getPreloadText( "{{Foo}}<noinclude> censored</noinclude> information <!-- is very secret -->", $title, $this->options ); @@ -135,7 +134,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategory() { + public function testTrackingCategory() { $title = Title::newFromText( __FUNCTION__ ); $catName = wfMessage( 'broken-file-category' )->inContentLanguage()->text(); $cat = Title::makeTitleSafe( NS_CATEGORY, $catName ); @@ -148,7 +147,7 @@ class ExtraParserTest extends MediaWikiTestCase { /** * @group Database */ - function testTrackingCategorySpecial() { + public function testTrackingCategorySpecial() { // Special pages shouldn't have tracking cats. $title = SpecialPage::getTitleFor( 'Contributions' ); $parserOutput = $this->parser->parse( "[[file:nonexistent]]", $title, $this->options ); diff --git a/tests/phpunit/includes/FallbackTest.php b/tests/phpunit/includes/FallbackTest.php new file mode 100644 index 00000000..f408f471 --- /dev/null +++ b/tests/phpunit/includes/FallbackTest.php @@ -0,0 +1,73 @@ +<?php + +/** + * @covers Fallback + */ +class FallbackTest extends MediaWikiTestCase { + + public 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( + call_user_func_array( 'mb_substr', $param_set ), + call_user_func_array( '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( + call_user_func_array( 'mb_strpos', $param_set ), + call_user_func_array( 'Fallback::mb_strpos', $param_set ), + 'Fallback mb_strpos with params ' . implode( ', ', $old_param_set ) + ); + + $this->assertEquals( + call_user_func_array( 'mb_strrpos', $param_set ), + call_user_func_array( 'Fallback::mb_strrpos', $param_set ), + 'Fallback mb_strrpos with params ' . implode( ', ', $old_param_set ) + ); + } + } + +}
\ No newline at end of file diff --git a/tests/phpunit/includes/FauxRequestTest.php b/tests/phpunit/includes/FauxRequestTest.php new file mode 100644 index 00000000..9f3aa11d --- /dev/null +++ b/tests/phpunit/includes/FauxRequestTest.php @@ -0,0 +1,15 @@ +<?php + +class FauxRequestTest extends MediaWikiTestCase { + + public function testGetSetHeader() { + $value = 'test/test'; + + $request = new FauxRequest(); + $request->setHeader( 'Content-Type', $value ); + + $this->assertEquals( $request->getHeader( 'Content-Type' ), $value ); + $this->assertEquals( $request->getHeader( 'CONTENT-TYPE' ), $value ); + $this->assertEquals( $request->getHeader( 'content-type' ), $value ); + } +} diff --git a/tests/phpunit/includes/FauxResponseTest.php b/tests/phpunit/includes/FauxResponseTest.php index 56691c9e..f9ba1b3b 100644 --- a/tests/phpunit/includes/FauxResponseTest.php +++ b/tests/phpunit/includes/FauxResponseTest.php @@ -30,13 +30,13 @@ class FauxResponseTest extends MediaWikiTestCase { $this->response = new FauxResponse; } - function testCookie() { + public 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() { + public function testHeader() { $this->assertEquals( null, $this->response->getheader( 'Location' ), 'Non-existing header' ); $this->response->header( 'Location: http://localhost/' ); @@ -47,9 +47,12 @@ class FauxResponseTest extends MediaWikiTestCase { $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' ); + + $this->response->header( 'Location: http://localhost/' ); + $this->assertEquals( 'http://localhost/', $this->response->getheader( 'LOCATION' ), 'Get header case insensitive' ); } - function testResponseCode() { + public function testResponseCode() { $this->response->header( 'HTTP/1.1 200' ); $this->assertEquals( 200, $this->response->getStatusCode(), 'Header with no message' ); diff --git a/tests/phpunit/includes/FormOptionsInitializationTest.php b/tests/phpunit/includes/FormOptionsInitializationTest.php index 4053683f..fb2304dc 100644 --- a/tests/phpunit/includes/FormOptionsInitializationTest.php +++ b/tests/phpunit/includes/FormOptionsInitializationTest.php @@ -81,5 +81,4 @@ class FormOptionsInitializationTest extends MediaWikiTestCase { $this->object->getOptions() ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php index 24fc47cf..6154df1d 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalTest.php @@ -29,7 +29,10 @@ class GlobalTest extends MediaWikiTestCase { parent::tearDown(); } - /** @dataProvider provideForWfArrayDiff2 */ + /** + * @dataProvider provideForWfArrayDiff2 + * @covers ::wfArrayDiff2 + */ public function testWfArrayDiff2( $a, $b, $expected ) { $this->assertEquals( wfArrayDiff2( $a, $b ), $expected @@ -53,25 +56,37 @@ class GlobalTest extends MediaWikiTestCase { ); } - function testRandom() { + /** + * @covers ::wfRandom + */ + public function testRandom() { # This could hypothetically fail, but it shouldn't ;) $this->assertFalse( wfRandom() == wfRandom() ); } - function testUrlencode() { + /** + * @covers ::wfUrlencode + */ + public function testUrlencode() { $this->assertEquals( "%E7%89%B9%E5%88%A5:Contributions/Foobar", wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); } - function testExpandIRI() { + /** + * @covers ::wfExpandIRI + */ + public 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() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlyEmpty() { global $wgReadOnly; $wgReadOnly = null; @@ -79,7 +94,10 @@ class GlobalTest extends MediaWikiTestCase { $this->assertFalse( wfReadOnly() ); } - function testReadOnlySet() { + /** + * @covers ::wfReadOnly + */ + public function testReadOnlySet() { global $wgReadOnly, $wgReadOnlyFile; $f = fopen( $wgReadOnlyFile, "wt" ); @@ -97,19 +115,6 @@ class GlobalTest extends MediaWikiTestCase { $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!" ); - } - public static function provideArrayToCGI() { return array( array( array(), '' ), // empty @@ -130,13 +135,17 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideArrayToCGI + * @covers ::wfArrayToCgi */ - function testArrayToCGI( $array, $result ) { + public function testArrayToCGI( $array, $result ) { $this->assertEquals( $result, wfArrayToCgi( $array ) ); } - function testArrayToCGI2() { + /** + * @covers ::testWfArrayDiff2 + */ + public function testArrayToCGI2() { $this->assertEquals( "baz=bar&foo=bar", wfArrayToCgi( @@ -161,8 +170,9 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiToArray + * @covers ::wfCgiToArray */ - function testCgiToArray( $cgi, $result ) { + public function testCgiToArray( $cgi, $result ) { $this->assertEquals( $result, wfCgiToArray( $cgi ) ); } @@ -181,12 +191,16 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideCgiRoundTrip + * @covers ::wfArrayToCgi */ - function testCgiRoundTrip( $cgi ) { + public function testCgiRoundTrip( $cgi ) { $this->assertEquals( $cgi, wfArrayToCgi( wfCgiToArray( $cgi ) ) ); } - function testMimeTypeMatch() { + /** + * @covers ::mimeTypeMatch + */ + public function testMimeTypeMatch() { $this->assertEquals( 'text/html', mimeTypeMatch( 'text/html', @@ -208,7 +222,10 @@ class GlobalTest extends MediaWikiTestCase { 'image/svg+xml' => 0.5 ) ) ); } - function testNegotiateType() { + /** + * @covers ::wfNegotiateType + */ + public function testNegotiateType() { $this->assertEquals( 'text/html', wfNegotiateType( @@ -249,77 +266,11 @@ class GlobalTest extends MediaWikiTestCase { 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() { + /** + * @covers ::wfDebug + * @covers ::wfDebugMem + */ + public function testDebugFunctionTest() { global $wgDebugLogFile, $wgDebugTimestamps; @@ -329,7 +280,6 @@ class GlobalTest extends MediaWikiTestCase { $old_wgDebugTimestamps = $wgDebugTimestamps; $wgDebugTimestamps = false; - wfDebug( "This is a normal string" ); $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) ); unlink( $wgDebugLogFile ); @@ -338,7 +288,6 @@ class GlobalTest extends MediaWikiTestCase { $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 ); @@ -351,12 +300,14 @@ class GlobalTest extends MediaWikiTestCase { $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) ); unlink( $wgDebugLogFile ); - $wgDebugLogFile = $old_log_file; $wgDebugTimestamps = $old_wgDebugTimestamps; } - function testClientAcceptsGzipTest() { + /** + * @covers ::wfClientAcceptsGzip + */ + public function testClientAcceptsGzipTest() { $settings = array( 'gzip' => true, @@ -387,7 +338,10 @@ class GlobalTest extends MediaWikiTestCase { } } - function testSwapVarsTest() { + /** + * @covers ::swap + */ + public function testSwapVarsTest() { $var1 = 1; $var2 = 2; @@ -398,10 +352,12 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $var1, 2, 'var1 is swapped' ); $this->assertEquals( $var2, 1, 'var2 is swapped' ); - } - function testWfPercentTest() { + /** + * @covers ::wfPercent + */ + public function testWfPercentTest() { $pcts = array( array( 6 / 7, '0.86%', 2, false ), @@ -429,6 +385,7 @@ class GlobalTest extends MediaWikiTestCase { /** * test @see wfShorthandToInteger() * @dataProvider provideShorthand + * @covers ::wfShorthandToInteger */ public function testWfShorthandToInteger( $shorthand, $expected ) { $this->assertEquals( $expected, @@ -439,7 +396,7 @@ class GlobalTest extends MediaWikiTestCase { /** array( shorthand, expected integer ) */ public static function provideShorthand() { return array( - # Null, empty ... + # Null, empty ... array( '', -1 ), array( ' ', -1 ), array( null, -1 ), @@ -489,6 +446,7 @@ class GlobalTest extends MediaWikiTestCase { * * @dataProvider provideMerge() * @group medium + * @covers ::wfMerge */ public function testMerge( $old, $mine, $yours, $expectedMergeResult, $expectedText ) { $this->checkHasDiff3(); @@ -564,13 +522,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideMakeUrlIndexes() + * @covers ::wfMakeUrlIndexes */ - function testMakeUrlIndexes( $url, $expected ) { + public function testMakeUrlIndexes( $url, $expected ) { $index = wfMakeUrlIndexes( $url ); $this->assertEquals( $expected, $index, "wfMakeUrlIndexes(\"$url\")" ); } - function provideMakeUrlIndexes() { + public static function provideMakeUrlIndexes() { return array( array( // just a regular :) @@ -621,13 +580,14 @@ class GlobalTest extends MediaWikiTestCase { /** * @dataProvider provideWfMatchesDomainList + * @covers ::wfMatchesDomainList */ - function testWfMatchesDomainList( $url, $domains, $expected, $description ) { + public function testWfMatchesDomainList( $url, $domains, $expected, $description ) { $actual = wfMatchesDomainList( $url, $domains ); $this->assertEquals( $expected, $actual, $description ); } - function provideWfMatchesDomainList() { + public static function provideWfMatchesDomainList() { $a = array(); $protocols = array( 'HTTP' => 'http:', 'HTTPS' => 'https:', 'protocol-relative' => '' ); foreach ( $protocols as $pDesc => $p ) { @@ -638,18 +598,30 @@ class GlobalTest extends MediaWikiTestCase { 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" ), + array( "$p//nds-nl.wikipedia.org", array( 'nl.wikipedia.org' ), false, "Non-matching substring of domain, $pDesc URL" ), ) ); } + return $a; } /** + * @covers ::wfMkdirParents + */ + public function testWfMkdirParents() { + // Should not return true if file exists instead of directory + $fname = $this->getNewTempFile(); + wfSuppressWarnings(); + $ok = wfMkdirParents( $fname ); + wfRestoreWarnings(); + $this->assertFalse( $ok ); + } + + /** * @dataProvider provideWfShellMaintenanceCmdList + * @covers ::wfShellMaintenanceCmd */ - function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { + public function testWfShellMaintenanceCmd( $script, $parameters, $options, $expected, $description ) { if ( wfIsWindows() ) { // Approximation that's good enough for our purposes just now $expected = str_replace( "'", '"', $expected ); @@ -658,8 +630,9 @@ class GlobalTest extends MediaWikiTestCase { $this->assertEquals( $expected, $actual, $description ); } - function provideWfShellMaintenanceCmdList() { + public static function provideWfShellMaintenanceCmdList() { global $wgPhpCli; + return array( array( 'eval.php', array( '--help', '--test' ), array(), "'$wgPhpCli' 'eval.php' '--help' '--test'", @@ -675,5 +648,5 @@ class GlobalTest extends MediaWikiTestCase { "Called eval.php --help --test with wrapper and php option" ), ); } - /* TODO: many more! */ + /* @TODO many more! */ } diff --git a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php index 4879a38d..cf891e7b 100644 --- a/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php +++ b/tests/phpunit/includes/GlobalFunctions/GlobalWithDBTest.php @@ -6,13 +6,15 @@ class GlobalWithDBTest extends MediaWikiTestCase { /** * @dataProvider provideWfIsBadImageList + * @covers ::wfIsBadImage */ - function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { + public function testWfIsBadImage( $name, $title, $blacklist, $expected, $desc ) { $this->assertEquals( $expected, wfIsBadImage( $name, $title, $blacklist ), $desc ); } - function provideWfIsBadImageList() { + public static function provideWfIsBadImageList() { $blacklist = '* [[File:Bad.jpg]] except [[Nasty page]]'; + return array( array( 'Bad.jpg', false, $blacklist, true, 'Called on a bad image' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php index 4bd8c685..9bb74873 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfAssembleUrlTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfAssembleUrl() + * @covers ::wfAssembleUrl */ class WfAssembleUrlTest extends MediaWikiTestCase { - /** @dataProvider provideURLParts */ + /** + * @dataProvider provideURLParts + */ public function testWfAssembleUrl( $parts, $output ) { $partsDump = print_r( $parts, true ); $this->assertEquals( @@ -87,7 +89,6 @@ class WfAssembleUrlTest extends MediaWikiTestCase { $url .= '#' . $fragment; } - $cases[] = array( $parts, $url, diff --git a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php index 8df038dd..a01c0d49 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBCP47() + * @covers ::wfBCP47 */ class WfBCP47Test extends MediaWikiTestCase { /** @@ -13,7 +13,7 @@ class WfBCP47Test extends MediaWikiTestCase { * @see http://tools.ietf.org/html/bcp47 * @dataProvider provideLanguageCodes() */ - function testBCP47( $code, $expected ) { + public function testBCP47( $code, $expected ) { $code = strtolower( $code ); $this->assertEquals( $expected, wfBCP47( $code ), "Applying BCP47 standard to lower case '$code'" @@ -28,7 +28,7 @@ class WfBCP47Test extends MediaWikiTestCase { /** * Array format is ($code, $expected) */ - function provideLanguageCodes() { + public static function provideLanguageCodes() { return array( // Extracted from BCP47 (list not exhaustive) # 2.1.1 @@ -115,20 +115,6 @@ class WfBCP47Test extends MediaWikiTestCase { // 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/wfBaseConvertTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php index 10b62b3c..7da804e6 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseConvertTest.php @@ -1,6 +1,6 @@ <?php /** - * Tests for wfBaseConvert() + * @covers ::wfBaseConvert */ class WfBaseConvertTest extends MediaWikiTestCase { public static function provideSingleDigitConversions() { @@ -152,6 +152,7 @@ class WfBaseConvertTest extends MediaWikiTestCase { $x[] = array( $base, $str ); } + return $x; } diff --git a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php index 407be8d2..8c548040 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfBaseNameTest.php @@ -1,17 +1,17 @@ <?php /** - * Tests for wfBaseName() + * @covers ::wfBaseName */ class WfBaseNameTest extends MediaWikiTestCase { /** * @dataProvider providePaths */ - function testBaseName( $fullpath, $basename ) { + public function testBaseName( $fullpath, $basename ) { $this->assertEquals( $basename, wfBaseName( $fullpath ), "wfBaseName('$fullpath') => '$basename'" ); } - function providePaths() { + public static function providePaths() { return array( array( '', '' ), array( '/', '' ), diff --git a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php index c1225e3e..41230a1e 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfExpandUrlTest.php @@ -1,16 +1,17 @@ <?php /** - * Tests for wfExpandUrl() + * @covers ::wfExpandUrl */ class WfExpandUrlTest extends MediaWikiTestCase { - /** @dataProvider provideExpandableUrls */ + /** + * @dataProvider provideExpandableUrls + */ public function testWfExpandUrl( $fullUrl, $shortUrl, $defaultProto, $server, $canServer, $httpsMode, $message ) { // Fake $wgServer and $wgCanonicalServer - global $wgServer, $wgCanonicalServer; - $oldServer = $wgServer; - $oldCanServer = $wgCanonicalServer; - $wgServer = $server; - $wgCanonicalServer = $canServer; + $this->setMwGlobals( array( + 'wgServer' => $server, + 'wgCanonicalServer' => $canServer, + ) ); // Fake $_SERVER['HTTPS'] if needed if ( $httpsMode ) { @@ -20,10 +21,6 @@ class WfExpandUrlTest extends MediaWikiTestCase { } $this->assertEquals( $fullUrl, wfExpandUrl( $shortUrl, $defaultProto ), $message ); - - // Restore $wgServer and $wgCanonicalServer - $wgServer = $oldServer; - $wgCanonicalServer = $oldCanServer; } /** @@ -108,6 +105,7 @@ class WfExpandUrlTest extends MediaWikiTestCase { } } } + return $retval; } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php index 58cf6b95..62296245 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfGetCallerTest.php @@ -1,8 +1,11 @@ <?php +/** + * @covers ::wfGetCaller + */ class WfGetCallerTest extends MediaWikiTestCase { - function testZero() { + public function testZero() { $this->assertEquals( __METHOD__, wfGetCaller( 1 ) ); } @@ -10,7 +13,7 @@ class WfGetCallerTest extends MediaWikiTestCase { return wfGetCaller(); } - function testOne() { + public function testOne() { $this->assertEquals( 'WfGetCallerTest::testOne', self::callerOne() ); } @@ -18,18 +21,20 @@ class WfGetCallerTest extends MediaWikiTestCase { if ( $n > 0 ) { return self::intermediateFunction( $level, $n - 1 ); } + return wfGetCaller( $level ); } - function testTwo() { + public function testTwo() { $this->assertEquals( 'WfGetCallerTest::testTwo', self::intermediateFunction() ); } - function testN() { + public function testN() { $this->assertEquals( 'WfGetCallerTest::testN', self::intermediateFunction( 2, 0 ) ); $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( 1, 0 ) ); - for ( $i = 0; $i < 10; $i++ ) + for ( $i = 0; $i < 10; $i++ ) { $this->assertEquals( 'WfGetCallerTest::intermediateFunction', self::intermediateFunction( $i + 1, $i ) ); + } } } diff --git a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php index 841a1b12..5032dc11 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfParseUrlTest.php @@ -1,7 +1,5 @@ <?php /** - * Tests for wfParseUrl() - * * Copyright © 2013 Alexandre Emsenhuber * * This program is free software; you can redistribute it and/or modify @@ -22,6 +20,9 @@ * @file */ +/** + * @covers ::wfParseUrl + */ class WfParseUrlTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); @@ -31,7 +32,9 @@ class WfParseUrlTest extends MediaWikiTestCase { ) ); } - /** @dataProvider provideURLs */ + /** + * @dataProvider provideURLs + */ public function testWfParseUrl( $url, $parts ) { $partsDump = var_export( $parts, true ); $this->assertEquals( diff --git a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php index 67861eeb..238a2c9c 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfRemoveDotSegmentsTest.php @@ -1,9 +1,11 @@ <?php /** - * Tests for wfRemoveDotSegments() + *@covers ::wfRemoveDotSegments */ class WfRemoveDotSegmentsTest extends MediaWikiTestCase { - /** @dataProvider providePaths */ + /** + * @dataProvider providePaths + */ public function testWfRemoveDotSegments( $inputPath, $outputPath ) { $this->assertEquals( $outputPath, diff --git a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php index 9d66d6b9..aadec87f 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfShorthandToIntegerTest.php @@ -1,10 +1,13 @@ <?php +/** + * @covers ::wfShorthandToInteger + */ class WfShorthandToIntegerTest extends MediaWikiTestCase { /** * @dataProvider provideABunchOfShorthands */ - function testWfShorthandToInteger( $input, $output, $description ) { + public function testWfShorthandToInteger( $input, $output, $description ) { $this->assertEquals( wfShorthandToInteger( $input ), $output, @@ -12,7 +15,7 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { ); } - function provideABunchOfShorthands() { + public static function provideABunchOfShorthands() { return array( array( '', -1, 'Empty string' ), array( ' ', -1, 'String of spaces' ), @@ -24,5 +27,4 @@ class WfShorthandToIntegerTest extends MediaWikiTestCase { array( '1k', 1024, 'One kb lowercased' ), ); } - } diff --git a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php index cf1830f5..5998f186 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfTimestampTest.php @@ -1,17 +1,18 @@ <?php /* - * Tests for wfTimestamp() + * @covers ::wfTimestamp */ class WfTimestampTest extends MediaWikiTestCase { /** * @dataProvider provideNormalTimestamps */ - function testNormalTimestamps( $input, $format, $output, $desc ) { + public function testNormalTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideNormalTimestamps() { + public static function provideNormalTimestamps() { $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); + return array( // TS_UNIX array( $t, TS_MW, '20010115123456', 'TS_UNIX to TS_MW' ), @@ -56,11 +57,11 @@ class WfTimestampTest extends MediaWikiTestCase { * See r74778 and bug 25451 * @dataProvider provideOldTimestamps */ - function testOldTimestamps( $input, $format, $output, $desc ) { + public function testOldTimestamps( $input, $format, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( $format, $input ), $desc ); } - function provideOldTimestamps() { + public static 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' ), @@ -95,11 +96,11 @@ class WfTimestampTest extends MediaWikiTestCase { * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 * @dataProvider provideHttpDates */ - function testHttpDate( $input, $output, $desc ) { + public function testHttpDate( $input, $output, $desc ) { $this->assertEquals( $output, wfTimestamp( TS_MW, $input ), $desc ); } - function provideHttpDates() { + public static 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' ), @@ -113,9 +114,9 @@ class WfTimestampTest extends MediaWikiTestCase { * 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() { + public function testTimestampParameter() { $now = wfTimestamp( TS_UNIX ); - // We check that wfTimestamp doesn't return false (error) and use a LessThan assert + // 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 ); diff --git a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php index 77685d50..ce6c82c5 100644 --- a/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php +++ b/tests/phpunit/includes/GlobalFunctions/wfUrlencodeTest.php @@ -1,18 +1,21 @@ <?php /** - * Tests for wfUrlencode() - * * The function only need a string parameter and might react to IIS7.0 + * @covers ::wfUrlencode */ class WfUrlencodeTest extends MediaWikiTestCase { #### TESTS ############################################################## - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWith( $input, $expected ) { $this->verifyEncodingFor( 'Apache', $input, $expected ); } - /** @dataProvider provideURLS */ + /** + * @dataProvider provideURLS + */ public function testEncodingUrlWithMicrosoftIis7( $input, $expected ) { $this->verifyEncodingFor( 'Microsoft-IIS/7', $input, $expected ); } diff --git a/tests/phpunit/includes/HTMLCheckMatrixTest.php b/tests/phpunit/includes/HTMLCheckMatrixTest.php new file mode 100644 index 00000000..5bbafd37 --- /dev/null +++ b/tests/phpunit/includes/HTMLCheckMatrixTest.php @@ -0,0 +1,102 @@ +<?php + +/** + * Unit tests for the HTMLCheckMatrix form field + */ +class HtmlCheckMatrixTest extends MediaWikiTestCase { + static private $defaultOptions = array( + 'rows' => array( 'r1', 'r2' ), + 'columns' => array( 'c1', 'c2' ), + 'fieldname' => 'test', + ); + + public function testPlainInstantiation() { + try { + $form = new HTMLCheckMatrix( array() ); + } catch ( MWException $e ) { + $this->assertInstanceOf( 'HTMLFormFieldRequiredOptionsException', $e ); + return; + } + + $this->fail( 'Expected MWException indicating missing parameters but none was thrown.' ); + } + + public function testInstantiationWithMinimumRequiredParameters() { + $form = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( true ); // form instantiation must throw exception on failure + } + + public function testValidateCallsUserDefinedValidationCallback() { + $called = false; + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'validation-callback' => function() use ( &$called ) { + $called = true; + return false; + }, + ) ); + $this->assertEquals( false, $this->validate( $field, array() ) ); + $this->assertTrue( $called ); + } + + public function testValidateRequiresArrayInput() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertEquals( false, $this->validate( $field, null ) ); + $this->assertEquals( false, $this->validate( $field, true ) ); + $this->assertEquals( false, $this->validate( $field, 'abc' ) ); + $this->assertEquals( false, $this->validate( $field, new stdClass ) ); + $this->assertEquals( true, $this->validate( $field, array() ) ); + } + + public function testValidateAllowsOnlyKnownTags() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertInternalType( 'string', $this->validate( $field, array( 'foo' ) ) ); + } + + public function testValidateAcceptsPartialTagList() { + $field = new HTMLCheckMatrix( self::$defaultOptions ); + $this->assertTrue( $this->validate( $field, array() ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1' ) ) ); + $this->assertTrue( $this->validate( $field, array( 'c1-r1', 'c1-r2', 'c2-r1', 'c2-r2' ) ) ); + } + + /** + * This form object actually has no visibility into what happens later on, but essentially + * if the data submitted by the user passes validate the following is run: + * foreach ( $field->filterDataForSubmit( $data ) as $k => $v ) { + * $user->setOption( $k, $v ); + * } + */ + public function testValuesForcedOnRemainOn() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-on' => array( 'c2-r1' ), + ) ); + $expected = array( + 'c1-r1' => false, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + $this->assertEquals( $expected, $field->filterDataForSubmit( array() ) ); + } + + public function testValuesForcedOffRemainOff() { + $field = new HTMLCheckMatrix( self::$defaultOptions + array( + 'force-options-off' => array( 'c1-r2', 'c2-r2' ), + ) ); + $expected = array( + 'c1-r1' => true, + 'c1-r2' => false, + 'c2-r1' => true, + 'c2-r2' => false, + ); + // array_keys on the result simulates submitting all fields checked + $this->assertEquals( $expected, $field->filterDataForSubmit( array_keys( $expected ) ) ); + } + + protected function validate( HTMLFormField $field, $submitted ) { + return $field->validate( + $submitted, + array( self::$defaultOptions['fieldname'] => $submitted ) + ); + } +} diff --git a/tests/phpunit/includes/HashRingTest.php b/tests/phpunit/includes/HashRingTest.php new file mode 100644 index 00000000..65f13696 --- /dev/null +++ b/tests/phpunit/includes/HashRingTest.php @@ -0,0 +1,53 @@ +<?php + +/** + * @group HashRing + */ +class HashRingTest extends MediaWikiTestCase { + public function testHashRing() { + $ring = new HashRing( array( 's1' => 1, 's2' => 1, 's3' => 2, 's4' => 2, 's5' => 2, 's6' => 3 ) ); + + $locations = array(); + for ( $i = 0; $i < 20; $i++ ) { + $locations[ "hello$i"] = $ring->getLocation( "hello$i" ); + } + $expectedLocations = array( + "hello0" => "s5", + "hello1" => "s6", + "hello2" => "s2", + "hello3" => "s5", + "hello4" => "s6", + "hello5" => "s4", + "hello6" => "s5", + "hello7" => "s4", + "hello8" => "s5", + "hello9" => "s5", + "hello10" => "s3", + "hello11" => "s6", + "hello12" => "s1", + "hello13" => "s3", + "hello14" => "s3", + "hello15" => "s5", + "hello16" => "s4", + "hello17" => "s6", + "hello18" => "s6", + "hello19" => "s3" + ); + + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + + $locations = array(); + for ( $i = 0; $i < 5; $i++ ) { + $locations[ "hello$i"] = $ring->getLocations( "hello$i", 2 ); + } + + $expectedLocations = array( + "hello0" => array( "s5", "s6" ), + "hello1" => array( "s6", "s4" ), + "hello2" => array( "s2", "s1" ), + "hello3" => array( "s5", "s6" ), + "hello4" => array( "s6", "s4" ), + ); + $this->assertEquals( $expectedLocations, $locations, 'Items placed at proper locations' ); + } +} diff --git a/tests/phpunit/includes/HooksTest.php b/tests/phpunit/includes/HooksTest.php index 89e789b1..81dd4870 100644 --- a/tests/phpunit/includes/HooksTest.php +++ b/tests/phpunit/includes/HooksTest.php @@ -2,81 +2,62 @@ class HooksTest extends MediaWikiTestCase { - public function testOldStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - - $i = new NothingClass(); - + function setUp() { global $wgHooks; - - $wgHooks['MediaWikiHooksTest001'][] = array( $i, 'someNonStatic' ); - - wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - - $this->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'; - + parent::setUp(); + Hooks::clear( 'MediaWikiHooksTest001' ); unset( $wgHooks['MediaWikiHooksTest001'] ); - } - public function testNewStyleHooks() { - $foo = 'Foo'; - $bar = 'Bar'; - + public static function provideHooks() { $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'; + return array( + array( 'Object and method', array( $i, 'someNonStatic' ), 'changed-nonstatic', 'changed-nonstatic' ), + array( 'Object and no method', array( $i ), 'changed-onevent', 'original' ), + array( 'Object and method with data', array( $i, 'someNonStaticWithData', 'data' ), 'data', 'original' ), + array( 'Object and static method', array( $i, 'someStatic' ), 'changed-static', 'original' ), + array( 'Class::method static call', array( 'NothingClass::someStatic' ), 'changed-static', 'original' ), + array( 'Global function', array( 'NothingFunction' ), 'changed-func', 'original' ), + array( 'Global function with data', array( 'NothingFunctionData', 'data' ), 'data', 'original' ), + array( 'Closure', array( function ( &$foo, $bar ) { + $foo = 'changed-closure'; + + return true; + } ), 'changed-closure', 'original' ), + array( 'Closure with data', array( function ( $data, &$foo, $bar ) { + $foo = $data; + + return true; + }, 'data' ), 'data', 'original' ) + ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someNonStaticWithData', 'baz' ) ); + /** + * @dataProvider provideHooks + */ + public function testOldStyleHooks( $msg, array $hook, $expectedFoo, $expectedBar ) { + global $wgHooks; + $foo = $bar = 'original'; - Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); + $wgHooks['MediaWikiHooksTest001'][] = $hook; + wfRunHooks( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'baz', $foo, 'Data included' ); - $foo = 'Foo'; + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); + } - Hooks::register( 'MediaWikiHooksTest001', array( $i, 'someStatic' ) ); + /** + * @dataProvider provideHooks + */ + public function testNewStyleHooks( $msg, $hook, $expectedFoo, $expectedBar ) { + $foo = $bar = 'original'; + Hooks::register( 'MediaWikiHooksTest001', $hook ); Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); - $this->assertEquals( 'bah', $foo, 'Standard static method' ); - $foo = 'Foo'; - - Hooks::clear( 'MediaWikiHooksTest001' ); + $this->assertSame( $expectedFoo, $foo, $msg ); + $this->assertSame( $expectedBar, $bar, $msg ); } public function testNewStyleHookInteraction() { @@ -85,10 +66,6 @@ class HooksTest extends MediaWikiTestCase { $a = new NothingClass(); $b = new NothingClass(); - // make sure to start with a clean slate - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); - $wgHooks['MediaWikiHooksTest001'][] = $a; $this->assertTrue( Hooks::isRegistered( 'MediaWikiHooksTest001' ), 'Hook registered via $wgHooks should be noticed by Hooks::isRegistered' ); @@ -101,37 +78,81 @@ class HooksTest extends MediaWikiTestCase { Hooks::run( 'MediaWikiHooksTest001', array( &$foo, &$bar ) ); $this->assertEquals( 1, $a->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); $this->assertEquals( 1, $b->calls, 'Hooks::run() should run hooks registered via wgHooks as well as Hooks::register' ); + } - // clean up - Hooks::clear( 'MediaWikiHooksTest001' ); - unset( $wgHooks['MediaWikiHooksTest001'] ); + /** + * @expectedException MWException + */ + public function testUncallableFunction() { + Hooks::register( 'MediaWikiHooksTest001', 'ThisFunctionDoesntExist' ); + Hooks::run( 'MediaWikiHooksTest001', array() ); } + + public function testFalseReturn() { + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + return false; + } ); + Hooks::register( 'MediaWikiHooksTest001', function ( &$foo ) { + $foo = 'test'; + + return true; + } ); + $foo = 'original'; + Hooks::run( 'MediaWikiHooksTest001', array( &$foo ) ); + $this->assertSame( 'original', $foo, 'Hooks continued processing after a false return.' ); + } + + /** + * @expectedException FatalError + */ + public function testFatalError() { + Hooks::register( 'MediaWikiHooksTest001', function () { + return 'test'; + } ); + Hooks::run( 'MediaWikiHooksTest001', array() ); + } +} + +function NothingFunction( &$foo, &$bar ) { + $foo = 'changed-func'; + + return true; +} + +function NothingFunctionData( $data, &$foo, &$bar ) { + $foo = $data; + + return true; } class NothingClass { public $calls = 0; public static function someStatic( &$foo, &$bar ) { - $foo = 'bah'; + $foo = 'changed-static'; + return true; } public function someNonStatic( &$foo, &$bar ) { $this->calls++; - $foo = 'fOO'; - $bar = 'bAR'; + $foo = 'changed-nonstatic'; + $bar = 'changed-nonstatic'; + return true; } public function onMediaWikiHooksTest001( &$foo, &$bar ) { $this->calls++; - $foo = 'foo'; + $foo = 'changed-onevent'; + return true; } - public function someNonStaticWithData( $foo, &$bar ) { + public function someNonStaticWithData( $data, &$foo, &$bar ) { $this->calls++; - $bar = $foo; + $foo = $data; + return true; } } diff --git a/tests/phpunit/includes/HtmlFormatterTest.php b/tests/phpunit/includes/HtmlFormatterTest.php new file mode 100644 index 00000000..a37df74f --- /dev/null +++ b/tests/phpunit/includes/HtmlFormatterTest.php @@ -0,0 +1,81 @@ +<?php + +/** + * @group HtmlFormatter + */ +class HtmlFormatterTest extends MediaWikiTestCase { + /** + * @dataProvider getHtmlData + */ + public function testTransform( $input, $expected, $callback = false ) { + $input = self::normalize( $input ); + $formatter = new HtmlFormatter( HtmlFormatter::wrapHTML( $input ) ); + if ( $callback ) { + $callback( $formatter ); + } + $formatter->filterContent(); + $html = $formatter->getText(); + $this->assertEquals( self::normalize( $expected ), self::normalize( $html ) ); + } + + private static function normalize( $s ) { + return str_replace( "\n", '', + str_replace( "\r", '', $s ) // "yay" to Windows! + ); + } + + public function getHtmlData() { + $removeImages = function( HtmlFormatter $f ) { + $f->setRemoveMedia(); + }; + $removeTags = function( HtmlFormatter $f ) { + $f->remove( array( 'table', '.foo', '#bar', 'div.baz' ) ); + }; + $flattenSomeStuff = function( HtmlFormatter $f ) { + $f->flatten( array( 's', 'div' ) ); + }; + $flattenEverything = function( HtmlFormatter $f ) { + $f->flattenAllTags(); + }; + return array( + // remove images if asked + array( + '<img src="/foo/bar.jpg" alt="Blah"/>', + '', + $removeImages, + ), + // basic tag removal + array( + '<table><tr><td>foo</td></tr></table><div class="foo">foo</div><div class="foo quux">foo</div><span id="bar">bar</span> +<strong class="foo" id="bar">foobar</strong><div class="notfoo">test</div><div class="baz"/> +<span class="baz">baz</span>', + + '<div class="notfoo">test</div> +<span class="baz">baz</span>', + $removeTags, + ), + // don't flatten tags that start like chosen ones + array( + '<div><s>foo</s> <span>bar</span></div>', + 'foo <span>bar</span>', + $flattenSomeStuff, + ), + // total flattening + array( + '<div style="foo">bar<sup>2</sup></div>', + 'bar2', + $flattenEverything, + ), + // UTF-8 preservation and security + array( + '<span title="" \' &"><Тест!></span> &<&&&&', + '<span title="" \' &"><Тест!></span> &<&&&&', + ), + // https://bugzilla.wikimedia.org/show_bug.cgi?id=53086 + array( + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + 'Foo<sup id="cite_ref-1" class="reference"><a href="#cite_note-1">[1]</a></sup> <a href="/wiki/Bar" title="Bar" class="mw-redirect">Bar</a>', + ), + ); + } +} diff --git a/tests/phpunit/includes/HtmlTest.php b/tests/phpunit/includes/HtmlTest.php index 590664e8..1c62d032 100644 --- a/tests/phpunit/includes/HtmlTest.php +++ b/tests/phpunit/includes/HtmlTest.php @@ -37,14 +37,11 @@ class HtmlTest extends MediaWikiTestCase { 'wgLanguageCode' => $langCode, 'wgContLang' => $langObj, 'wgLang' => $langObj, - 'wgHtml5' => true, 'wgWellFormedXml' => false, ) ); } public function testElementBasics() { - global $wgWellFormedXml; - $this->assertEquals( '<img>', Html::element( 'img', null, '' ), @@ -63,7 +60,7 @@ class HtmlTest extends MediaWikiTestCase { 'Close tag for empty element (array, string)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( '<img />', @@ -72,6 +69,31 @@ class HtmlTest extends MediaWikiTestCase { ); } + public function dataXmlMimeType() { + return array( + // ( $mimetype, $isXmlMimeType ) + # HTML is not an XML MimeType + array( 'text/html', false ), + # XML is an XML MimeType + array( 'text/xml', true ), + array( 'application/xml', true ), + # XHTML is an XML MimeType + array( 'application/xhtml+xml', true ), + # Make sure other +xml MimeTypes are supported + # SVG is another random MimeType even though we don't use it + array( 'image/svg+xml', true ), + # Complete random other MimeTypes are not XML + array( 'text/plain', false ), + ); + } + + /** + * @dataProvider dataXmlMimeType + */ + public function testXmlMimeType( $mimetype, $isXmlMimeType ) { + $this->assertEquals( $isXmlMimeType, Html::isXmlMimeType( $mimetype ) ); + } + public function testExpandAttributesSkipsNullAndFalse() { ### EMPTY ######## @@ -90,8 +112,6 @@ class HtmlTest extends MediaWikiTestCase { } public function testExpandAttributesForBooleans() { - global $wgHtml5, $wgWellFormedXml; - $this->assertEquals( '', Html::expandAttributes( array( 'selected' => false ) ), @@ -114,21 +134,13 @@ class HtmlTest extends MediaWikiTestCase { 'Boolean attributes have no value when value is true (passed as numerical array)' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' selected=""', Html::expandAttributes( array( 'selected' => true ) ), 'Boolean attributes have empty string value when value is true (wgWellFormedXml)' ); - - $wgHtml5 = false; - - $this->assertEquals( - ' selected="selected"', - Html::expandAttributes( array( 'selected' => true ) ), - 'Boolean attributes have their key as value when value is true (wgWellFormedXml, wgHTML5 = false)' - ); } /** @@ -136,8 +148,6 @@ class HtmlTest extends MediaWikiTestCase { * Please note it output a string prefixed with a space! */ public function testExpandAttributesVariousExpansions() { - global $wgWellFormedXml; - ### NOT EMPTY #### $this->assertEquals( ' empty_string=""', @@ -160,7 +170,7 @@ class HtmlTest extends MediaWikiTestCase { 'Number 0 value needs no quotes' ); - $wgWellFormedXml = true; + $this->setMwGlobals( 'wgWellFormedXml', true ); $this->assertEquals( ' empty_string=""', @@ -240,7 +250,7 @@ class HtmlTest extends MediaWikiTestCase { * Test feature added by r96188, let pass attributes values as * a PHP array. Restricted to class,rel, accesskey. */ - function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { + public function testExpandAttributesSpaceSeparatedAttributesWithBoolean() { $this->assertEquals( ' class="booltrue one"', Html::expandAttributes( array( 'class' => array( @@ -264,7 +274,7 @@ class HtmlTest extends MediaWikiTestCase { * * Feature added by r96188 */ - function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { + public function testValueIsAuthoritativeInSpaceSeparatedAttributesArrays() { $this->assertEquals( ' class=""', Html::expandAttributes( array( 'class' => array( @@ -275,7 +285,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testNamespaceSelector() { + public function testNamespaceSelector() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=0>(Main)</option>' . "\n" . @@ -354,7 +364,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanFilterOutNamespaces() { + public function testCanFilterOutNamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option value=2>User</option>' . "\n" . @@ -376,7 +386,7 @@ class HtmlTest extends MediaWikiTestCase { ); } - function testCanDisableANamespaces() { + public function testCanDisableANamespaces() { $this->assertEquals( '<select id=namespace name=namespace>' . "\n" . '<option disabled value=0>(Main)</option>' . "\n" . @@ -406,7 +416,7 @@ class HtmlTest extends MediaWikiTestCase { /** * @dataProvider provideHtml5InputTypes */ - function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { + public function testHtmlElementAcceptsNewHtml5TypesInHtml5Mode( $HTML5InputType ) { $this->assertEquals( '<input type=' . $HTML5InputType . '>', Html::element( 'input', array( 'type' => $HTML5InputType ) ), @@ -418,7 +428,7 @@ class HtmlTest extends MediaWikiTestCase { * List of input element types values introduced by HTML5 * Full list at http://www.w3.org/TR/html-markup/input.html */ - function provideHtml5InputTypes() { + public static function provideHtml5InputTypes() { $types = array( 'datetime', 'datetime-local', @@ -438,6 +448,7 @@ class HtmlTest extends MediaWikiTestCase { foreach ( $types as $type ) { $cases[] = array( $type ); } + return $cases; } @@ -446,7 +457,7 @@ class HtmlTest extends MediaWikiTestCase { * @covers Html::dropDefaults * @dataProvider provideElementsWithAttributesHavingDefaultValues */ - function testDropDefaults( $expected, $element, $attribs, $message = '' ) { + public function testDropDefaults( $expected, $element, $attribs, $message = '' ) { $this->assertEquals( $expected, Html::element( $element, $attribs ), $message ); } @@ -602,6 +613,7 @@ class HtmlTest extends MediaWikiTestCase { isset( $case[3] ) ? $case[3] : '' ); } + return $ret; } @@ -616,5 +628,4 @@ class HtmlTest extends MediaWikiTestCase { 'Allow special case "step=any".' ); } - } diff --git a/tests/phpunit/includes/HttpTest.php b/tests/phpunit/includes/HttpTest.php index 7698776c..11d8ed60 100644 --- a/tests/phpunit/includes/HttpTest.php +++ b/tests/phpunit/includes/HttpTest.php @@ -5,8 +5,9 @@ class HttpTest extends MediaWikiTestCase { /** * @dataProvider cookieDomains + * @covers Cookie::validateCookieDomain */ - function testValidateCookieDomain( $expected, $domain, $origin = null ) { + public function testValidateCookieDomain( $expected, $domain, $origin = null ) { if ( $origin ) { $ok = Cookie::validateCookieDomain( $domain, $origin ); $msg = "$domain against origin $origin"; @@ -50,8 +51,9 @@ class HttpTest extends MediaWikiTestCase { * Test Http::isValidURI() * @bug 27854 : Http::isValidURI is too lax * @dataProvider provideURI + * @covers Http::isValidURI */ - function testIsValidUri( $expect, $URI, $message = '' ) { + public function testIsValidUri( $expect, $URI, $message = '' ) { $this->assertEquals( $expect, (bool)Http::isValidURI( $URI ), @@ -132,7 +134,7 @@ class HttpTest extends MediaWikiTestCase { * rewritten when bug 29232 is taken care of (high-level handling of * HTTP redirects). */ - function testRelativeRedirections() { + public function testRelativeRedirections() { $h = MWHttpRequestTester::factory( 'http://oldsite/file.ext' ); # Forge a Location header @@ -176,7 +178,7 @@ class HttpTest extends MediaWikiTestCase { */ class MWHttpRequestTester extends MWHttpRequest { - // function derived from the MWHttpRequest factory function but + // function derived from the MWHttpRequest factory function but // returns appropriate tester class here public static function factory( $url, $options = null ) { if ( !Http::$httpEngine ) { @@ -194,6 +196,7 @@ class MWHttpRequestTester extends MWHttpRequest { throw new MWException( __METHOD__ . ': allow_url_fopen needs to be enabled for pure PHP' . ' http requests to work. If possible, curl should be used instead. See http://php.net/curl.' ); } + return new PhpHttpRequestTester( $url, $options ); default: } diff --git a/tests/phpunit/includes/IPTest.php b/tests/phpunit/includes/IPTest.php index 7bc29385..c074eea6 100644 --- a/tests/phpunit/includes/IPTest.php +++ b/tests/phpunit/includes/IPTest.php @@ -1,7 +1,12 @@ <?php /** - * Tests for IP validity functions. Ported from /t/inc/IP.t by avar. + * Tests for IP validity functions. + * + * Ported from /t/inc/IP.t by avar. + * * @group IP + * @todo Test methods in this call should be split into a method and a + * dataprovider. */ class IPTest extends MediaWikiTestCase { @@ -259,14 +264,63 @@ class IPTest extends MediaWikiTestCase { } /** - * test wrapper around ip2long which might return -1 or false depending on PHP version * @covers IP::toUnsigned + * @dataProvider provideToUnsigned */ - 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 ) ); + public function testToUnsigned( $expected, $input ) { + $result = IP::toUnsigned( $input ); + $this->assertTrue( $result === false || is_string( $result ) || is_int( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToUnsigned() + */ + public static function provideToUnsigned() { + return array( + array( 1, '0.0.0.1' ), + array( 16909060, '1.2.3.4' ), + array( 2130706433, '127.0.0.1' ), + array( '2147483648', '128.0.0.0' ), + array( '3735931646', '222.173.202.254' ), + array( pow( 2, 32 ) - 1, '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 1, '::1' ), + array( '42540766452641154071740215577757643572', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( '42540766452641154071740215577757643572', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); + } + + /** + * @covers IP::toHex + * @dataProvider provideToHex + */ + public function testToHex( $expected, $input ) { + $result = IP::toHex( $input ); + $this->assertTrue( $result === false || is_string( $result ) ); + $this->assertEquals( $expected, $result ); + } + + /** + * Provider for IP::testToHex() + */ + public static function provideToHex() { + return array( + array( '00000001', '0.0.0.1' ), + array( '01020304', '1.2.3.4' ), + array( '7F000001', '127.0.0.1' ), + array( '80000000', '128.0.0.0' ), + array( 'DEADCAFE', '222.173.202.254' ), + array( 'FFFFFFFF', '255.255.255.255' ), + array( false, 'IN.VA.LI.D' ), + array( 'v6-00000000000000000000000000000001', '::1' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334' ), + array( 'v6-20010DB885A3000000008A2E03707334', '2001:db8:85a3::8a2e:0370:7334' ), + array( false, 'IN:VA::LI:D' ), + array( false, ':::1' ) + ); } /** @@ -338,7 +392,7 @@ class IPTest extends MediaWikiTestCase { * representing the network mask and the bit mask. * @covers IP::parseCIDR */ - function testCIDRParsing() { + public function testCIDRParsing() { $this->assertFalseCIDR( '192.0.2.0', "missing mask" ); $this->assertFalseCIDR( '192.0.2.0/', "missing bitmask" ); @@ -435,7 +489,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::splitHostAndPort(). * @dataProvider provideSplitHostAndPort */ - function testSplitHostAndPort( $expected, $input, $description ) { + public function testSplitHostAndPort( $expected, $input, $description ) { $this->assertEquals( $expected, IP::splitHostAndPort( $input ), $description ); } @@ -462,7 +516,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::combineHostAndPort() * @dataProvider provideCombineHostAndPort */ - function testCombineHostAndPort( $expected, $input, $description ) { + public function testCombineHostAndPort( $expected, $input, $description ) { list( $host, $port, $defaultPort ) = $input; $this->assertEquals( $expected, @@ -486,7 +540,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::sanitizeRange() * @dataProvider provideIPCIDRs */ - function testSanitizeRange( $input, $expected, $description ) { + public function testSanitizeRange( $input, $expected, $description ) { $this->assertEquals( $expected, IP::sanitizeRange( $input ), $description ); } @@ -510,7 +564,7 @@ class IPTest extends MediaWikiTestCase { * Test for IP::prettifyIP() * @dataProvider provideIPsToPrettify */ - function testPrettifyIP( $ip, $prettified ) { + public function testPrettifyIP( $ip, $prettified ) { $this->assertEquals( $prettified, IP::prettifyIP( $ip ), "Prettify of $ip" ); } diff --git a/tests/phpunit/includes/JsonTest.php b/tests/phpunit/includes/JsonTest.php deleted file mode 100644 index 96a2ead5..00000000 --- a/tests/phpunit/includes/JsonTest.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -class JsonTest extends MediaWikiTestCase { - - function testPhpBug46944Test() { - $this->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 index d4d93b07..7c2134b9 100644 --- a/tests/phpunit/includes/LanguageConverterTest.php +++ b/tests/phpunit/includes/LanguageConverterTest.php @@ -30,39 +30,39 @@ class LanguageConverterTest extends MediaWikiLangTestCase { parent::tearDown(); } - function testGetPreferredVariantDefaults() { + public function testGetPreferredVariantDefaults() { $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaders() { + public function testGetPreferredVariantHeaders() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight() { + public function testGetPreferredVariantHeaderWeight() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderWeight2() { + public function testGetPreferredVariantHeaderWeight2() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderMulti() { + public function testGetPreferredVariantHeaderMulti() { global $wgRequest; $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantUserOption() { + public function testGetPreferredVariantUserOption() { global $wgUser; $wgUser = new User; @@ -75,7 +75,21 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantHeaderUserVsUrl() { + public function testGetPreferredVariantUserOptionForForeignLanguage() { + global $wgContLang, $wgUser; + + $wgContLang = Language::factory( 'en' ); + $wgUser = new User; + $wgUser->load(); // from 'defaults' + $wgUser->mId = 1; + $wgUser->mDataLoaded = true; + $wgUser->mOptionsLoaded = true; + $wgUser->setOption( 'variant-tg', 'tg-latn' ); + + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); + } + + public function testGetPreferredVariantHeaderUserVsUrl() { global $wgContLang, $wgRequest, $wgUser; $wgContLang = Language::factory( 'tg-latn' ); @@ -85,19 +99,19 @@ class LanguageConverterTest extends MediaWikiLangTestCase { $wgUser->mFrom = 'defaults'; $wgUser->mOptionsLoaded = true; // The user's data is ignored because the variant is set in the URL. - $wgUser->setOption( 'variant', 'tg-latn' ); + $wgUser->setOption( 'variant', 'tg-latn' ); $this->assertEquals( 'tg', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVariant() { + public function testGetPreferredVariantDefaultLanguageVariant() { global $wgDefaultLanguageVariant; $wgDefaultLanguageVariant = 'tg-latn'; $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant() ); } - function testGetPreferredVariantDefaultLanguageVsUrlVariant() { + public function testGetPreferredVariantDefaultLanguageVsUrlVariant() { global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; $wgContLang = Language::factory( 'tg-latn' ); @@ -123,7 +137,6 @@ class TestConverter extends LanguageConverter { 'tg' => new ReplacementArray() ); } - } class LanguageToTest extends Language { diff --git a/tests/phpunit/includes/LicensesTest.php b/tests/phpunit/includes/LicensesTest.php index 212b3b3b..478a2ffc 100644 --- a/tests/phpunit/includes/LicensesTest.php +++ b/tests/phpunit/includes/LicensesTest.php @@ -2,7 +2,7 @@ class LicensesTest extends MediaWikiTestCase { - function testLicenses() { + public function testLicenses() { $str = " * Free licenses: ** GFDL|Debian disagrees diff --git a/tests/phpunit/includes/LinkerTest.php b/tests/phpunit/includes/LinkerTest.php index e353c46c..b605f08f 100644 --- a/tests/phpunit/includes/LinkerTest.php +++ b/tests/phpunit/includes/LinkerTest.php @@ -6,7 +6,7 @@ class LinkerTest extends MediaWikiLangTestCase { * @dataProvider provideCasesForUserLink * @covers Linker::userLink */ - function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { + public function testUserLink( $expected, $userId, $userName, $altUserName = false, $msg = '' ) { $this->setMwGlobals( array( 'wgArticlePath' => '/wiki/$1', 'wgWellFormedXml' => true, @@ -17,7 +17,7 @@ class LinkerTest extends MediaWikiLangTestCase { ); } - function provideCasesForUserLink() { + public static function provideCasesForUserLink() { # Format: # - expected # - userid diff --git a/tests/phpunit/includes/LinksUpdateTest.php b/tests/phpunit/includes/LinksUpdateTest.php index a79b3a25..5ade250e 100644 --- a/tests/phpunit/includes/LinksUpdateTest.php +++ b/tests/phpunit/includes/LinksUpdateTest.php @@ -7,7 +7,7 @@ */ class LinksUpdateTest extends MediaWikiTestCase { - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -60,18 +60,30 @@ class LinksUpdateTest extends MediaWikiTestCase { $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( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Foo' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), // newFromText doesn't yield the same internal state.... + ), $update->getAddedLinks() ); $po = new ParserOutput(); $po->setTitleText( $t->getPrefixedText() ); $po->addLink( Title::newFromText( "Bar" ) ); + $po->addLink( Title::newFromText( "Talk:Bar" ) ); - $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( + $update = $this->assertLinksUpdate( $t, $po, 'pagelinks', 'pl_namespace, pl_title', 'pl_from = 111', array( array( NS_MAIN, 'Bar' ), + array( NS_TALK, 'Bar' ), ) ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Bar' ), + Title::makeTitle( NS_TALK, 'Bar' ), + ), $update->getAddedLinks() ); + $this->assertArrayEquals( array( + Title::makeTitle( NS_MAIN, 'Foo' ), + ), $update->getRemovedLinks() ); } public function testUpdate_externallinks() { @@ -122,7 +134,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addImage( "Foo.png" ); - $this->assertLinksUpdate( $t, $po, 'imagelinks', 'il_to', 'il_from = 111', array( array( 'Foo.png' ), ) ); @@ -133,7 +144,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $po->addLanguageLink( Title::newFromText( "en:Foo" )->getFullText() ); - $this->assertLinksUpdate( $t, $po, 'langlinks', 'll_lang, ll_title', 'll_from = 111', array( array( 'En', 'Foo' ), ) ); @@ -149,7 +159,7 @@ class LinksUpdateTest extends MediaWikiTestCase { ) ); } - #@todo: test recursive, too! + // @todo test recursive, too! protected function assertLinksUpdate( Title $title, ParserOutput $parserOutput, $table, $fields, $condition, array $expectedRows ) { $update = new LinksUpdate( $title, $parserOutput ); @@ -160,5 +170,6 @@ class LinksUpdateTest extends MediaWikiTestCase { $update->commitTransaction(); $this->assertSelect( $table, $fields, $condition, $expectedRows ); + return $update; } } diff --git a/tests/phpunit/includes/LocalFileTest.php b/tests/phpunit/includes/LocalFileTest.php index d6f0d2ee..2501c783 100644 --- a/tests/phpunit/includes/LocalFileTest.php +++ b/tests/phpunit/includes/LocalFileTest.php @@ -35,72 +35,72 @@ class LocalFileTest extends MediaWikiTestCase { $this->file_lc = $this->repo_lc->newFile( 'test!' ); } - function testGetHashPath() { + public 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() { + public 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() { + public 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() { + public 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() { + public 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() { + public 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() { + public 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() { + public 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() { + public 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() { + public function testGetUrl() { $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); } - function testWfLocalFile() { + public 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/MWExceptionHandlerTest.php b/tests/phpunit/includes/MWExceptionHandlerTest.php new file mode 100644 index 00000000..987dfa83 --- /dev/null +++ b/tests/phpunit/includes/MWExceptionHandlerTest.php @@ -0,0 +1,73 @@ +<?php +/** + * Tests for includes/Exception.php. + * + * @author Antoine Musso + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @file + */ + +class MWExceptionHandlerTest extends MediaWikiTestCase { + + /** + * @covers MWExceptionHandler::getRedactedTrace + */ + function testGetRedactedTrace() { + try { + $array = array( 'a', 'b' ); + $object = new StdClass(); + self::helperThrowAnException( $array, $object ); + } catch (Exception $e) { + } + + # Make sure our strack trace contains an array and an object passed to + # some function in the stacktrace. Else, we can not assert the trace + # redaction achieved its job. + $trace = $e->getTrace(); + $hasObject = false; + $hasArray = false; + foreach ( $trace as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $hasObject = $hasObject || is_object( $arg ); + $hasArray = $hasArray || is_array( $arg ); + } + + if( $hasObject && $hasArray ) { + break; + } + } + $this->assertTrue( $hasObject, + "The stacktrace must have a function having an object has parameter" ); + $this->assertTrue( $hasArray, + "The stacktrace must have a function having an array has parameter" ); + + # Now we redact the trace.. and make sure no function arguments are + # arrays or objects. + $redacted = MWExceptionHandler::getRedactedTrace( $e ); + + foreach ( $redacted as $frame ) { + if ( ! isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $this->assertNotInternalType( 'array', $arg); + $this->assertNotInternalType( 'object', $arg); + } + } + } + + /** + * Helper function for testExpandArgumentsInCall + * + * Pass it an object and an array :-) + * + * @throws Exception + */ + protected static function helperThrowAnException( $a, $b ) { + throw new Exception(); + } +} diff --git a/tests/phpunit/includes/MWFunctionTest.php b/tests/phpunit/includes/MWFunctionTest.php index 6c17bf48..d86f2c9b 100644 --- a/tests/phpunit/includes/MWFunctionTest.php +++ b/tests/phpunit/includes/MWFunctionTest.php @@ -1,27 +1,7 @@ <?php class MWFunctionTest extends MediaWikiTestCase { - function testCallUserFuncWorkarounds() { - $this->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() { + public function testNewObjFunction() { $arg1 = 'Foo'; $arg2 = 'Bar'; $arg3 = array( 'Baz' ); @@ -34,32 +14,7 @@ class MWFunctionTest extends MediaWikiTestCase { 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 { diff --git a/tests/phpunit/includes/MWNamespaceTest.php b/tests/phpunit/includes/MWNamespaceTest.php index 45f8dafc..10e9db61 100644 --- a/tests/phpunit/includes/MWNamespaceTest.php +++ b/tests/phpunit/includes/MWNamespaceTest.php @@ -125,7 +125,6 @@ class MWNamespaceTest extends MediaWikiTestCase { public function testGetAssociated() { $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) ); $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) ); - } ### Exceptions with getAssociated() @@ -201,7 +200,6 @@ class MWNamespaceTest extends MediaWikiTestCase { NS_SPECIAL, NS_MEDIA, "NS_SPECIAL and NS_MEDIA are different subject namespaces" ); - } /** @@ -346,33 +344,32 @@ class MWNamespaceTest extends MediaWikiTestCase { $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces(), + MWNamespace::getContentNamespaces(), '$wgContentNamespaces is an array with only NS_MAIN by default' ); - # test !is_array( $wgcontentNamespaces ) $wgContentNamespaces = ''; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = false; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = null; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); $wgContentNamespaces = 5; - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( NS_MAIN ), MWNamespace::getContentNamespaces() ); # test $wgContentNamespaces === array() $wgContentNamespaces = array(); - $this->assertEquals( NS_MAIN, MWNamespace::getcontentNamespaces() ); + $this->assertEquals( array( 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(), + MWNamespace::getContentNamespaces(), 'NS_MAIN is forced in $wgContentNamespaces even if unwanted' ); @@ -380,13 +377,13 @@ class MWNamespaceTest extends MediaWikiTestCase { $wgContentNamespaces = array( NS_MAIN ); $this->assertEquals( array( NS_MAIN ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); $wgContentNamespaces = array( NS_MAIN, NS_USER, NS_CATEGORY ); $this->assertEquals( array( NS_MAIN, NS_USER, NS_CATEGORY ), - MWNamespace::getcontentNamespaces() + MWNamespace::getContentNamespaces() ); } diff --git a/tests/phpunit/includes/MessageTest.php b/tests/phpunit/includes/MessageTest.php index c378bb8e..1e18f975 100644 --- a/tests/phpunit/includes/MessageTest.php +++ b/tests/phpunit/includes/MessageTest.php @@ -10,7 +10,7 @@ class MessageTest extends MediaWikiLangTestCase { ) ); } - function testExists() { + public function testExists() { $this->assertTrue( wfMessage( 'mainpage' )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); @@ -19,7 +19,7 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); } - function testKey() { + public function testKey() { $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) ); $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); @@ -28,47 +28,103 @@ class MessageTest extends MediaWikiLangTestCase { $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->escaped() ); } - function testInLanguage() { + public 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() { + public 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() { + public 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 testDeliciouslyManyParams() { + public function testDeliciouslyManyParams() { $msg = new RawMessage( '$1$2$3$4$5$6$7$8$9$10$11$12' ); // One less than above has placeholders $params = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k' ); $this->assertEquals( 'abcdefghijka2', $msg->params( $params )->plain(), 'Params > 9 are replaced correctly' ); } - function testInContentLanguage() { - global $wgLang, $wgForceUIMsgAsContentMsg; - $wgLang = Language::factory( 'fr' ); + /** + * FIXME: This should not need database, but Language#formatExpiry does (bug 55912) + * @group Database + */ + public function testMessageParamTypes() { + $lang = Language::factory( 'en' ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatNum( 123456.789 ), + $msg->inLanguage( $lang )->numParams( 123456.789 )->plain(), + 'numParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatDuration( 1234 ), + $msg->inLanguage( $lang )->durationParams( 1234 )->plain(), + 'durationParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatExpiry( wfTimestampNow() ), + $msg->inLanguage( $lang )->expiryParams( wfTimestampNow() )->plain(), + 'expiryParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatTimePeriod( 1234 ), + $msg->inLanguage( $lang )->timeperiodParams( 1234 )->plain(), + 'timeperiodParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatSize( 123456 ), + $msg->inLanguage( $lang )->sizeParams( 123456 )->plain(), + 'sizeParams is handled correctly' + ); + + $msg = new RawMessage( '$1' ); + $this->assertEquals( + $lang->formatBitrate( 123456 ), + $msg->inLanguage( $lang )->bitrateParams( 123456 )->plain(), + 'bitrateParams is handled correctly' + ); + } + + public function testInContentLanguageDisabled() { + $this->setMwGlobals( 'wgLang', Language::factory( 'fr' ) ); $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg disabled' ); - $wgForceUIMsgAsContentMsg['testInContentLanguage'] = 'mainpage'; + } + + public function testInContentLanguageEnabled() { + $this->setMwGlobals( array( + 'wgLang' => Language::factory( 'fr' ), + 'wgForceUIMsgAsContentMsg' => array( 'mainpage' ), + ) ); + $this->assertEquals( 'Accueil', wfMessage( 'mainpage' )->inContentLanguage()->plain(), 'ForceUIMsg enabled' ); } /** * @expectedException MWException */ - function testInLanguageThrows() { + public function testInLanguageThrows() { wfMessage( 'foo' )->inLanguage( 123 ); } } diff --git a/tests/phpunit/includes/OutputPageTest.php b/tests/phpunit/includes/OutputPageTest.php index 4084fb17..56bb0fce 100644 --- a/tests/phpunit/includes/OutputPageTest.php +++ b/tests/phpunit/includes/OutputPageTest.php @@ -19,7 +19,6 @@ class OutputPageTest extends MediaWikiTestCase { * * options['printableQuery'] - value of query string for printable, or omitted for none * options['handheldQuery'] - value of query string for handheld, or omitted for none - * options['handheldForIPhone'] - value of the $wgHandheldForIPhone global * options['media'] - passed into the method under the same name * options['expectedReturn'] - expected return value * options['message'] - PHPUnit message for assertion @@ -39,7 +38,6 @@ class OutputPageTest extends MediaWikiTestCase { $fauxRequest = new FauxRequest( $queryData, false ); $this->setMWGlobals( array( 'wgRequest' => $fauxRequest, - 'wgHandheldForIPhone' => $args['handheldForIPhone'] ) ); $actualReturn = OutputPage::transformCssMedia( $args['media'] ); @@ -47,50 +45,31 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests a case of transformCssMedia with both values of wgHandheldForIPhone. - * Used to verify that behavior is orthogonal to that option. - * - * If the value of wgHandheldForIPhone should matter, use assertTransformCssMediaCase. - * - * @param array $args key-value array of arguments as shown in assertTransformCssMediaCase. - * Will be mutated. - */ - protected function assertTransformCssMediaCaseWithBothHandheldForIPhone( $args ) { - $message = $args['message']; - foreach ( array( true, false ) as $handheldForIPhone ) { - $args['handheldForIPhone'] = $handheldForIPhone; - $stringHandheldForIPhone = var_export( $handheldForIPhone, true ); - $args['message'] = "$message. \$wgHandheldForIPhone was $stringHandheldForIPhone"; - $this->assertTransformCssMediaCase( $args ); - } - } - - /** * Tests print requests */ public function testPrintRequests() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On printable request, screen returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => null, 'message' => 'On printable request, screen media query with only returns null' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'printableQuery' => '1', 'media' => 'print', 'expectedReturn' => '', @@ -103,25 +82,30 @@ class OutputPageTest extends MediaWikiTestCase { */ public function testScreenRequests() { $this->assertTransformCssMediaCase( array( - 'handheldForIPhone' => false, 'media' => 'screen', 'expectedReturn' => 'screen', - 'message' => 'On screen request, with handheldForIPhone false, screen media type is preserved' + 'message' => 'On screen request, screen media type is preserved' + ) ); + + $this->assertTransformCssMediaCase( array( + 'media' => 'handheld', + 'expectedReturn' => 'handheld', + 'message' => 'On screen request, handheld media type is preserved' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_MEDIA_QUERY, 'message' => 'On screen request, screen media query is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => self::SCREEN_ONLY_MEDIA_QUERY, 'expectedReturn' => self::SCREEN_ONLY_MEDIA_QUERY, 'message' => 'On screen request, screen media query with only is preserved.' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'media' => 'print', 'expectedReturn' => 'print', 'message' => 'On screen request, print media type is preserved' @@ -129,44 +113,21 @@ class OutputPageTest extends MediaWikiTestCase { } /** - * Tests handheld and wgHandheldForIPhone behavior + * Tests handheld behavior */ public function testHandheld() { - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'handheld', 'expectedReturn' => '', 'message' => 'On request with handheld querystring and media is handheld, returns empty string' ) ); - $this->assertTransformCssMediaCaseWithBothHandheldForIPhone( array( + $this->assertTransformCssMediaCase( array( 'handheldQuery' => '1', 'media' => 'screen', 'expectedReturn' => null, 'message' => 'On request with handheld querystring and media is screen, returns null' ) ); - - // A bit counter-intuitively, $wgHandheldForIPhone should only matter if the query handheld is false or omitted - $this->assertTransformCssMediaCase( array( - 'handheldQuery' => '0', - 'media' => 'screen', - 'handheldForIPhone' => true, - 'expectedReturn' => 'screen and (min-device-width: 481px)', - 'message' => 'With $wgHandheldForIPhone true, screen media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => true, - 'expectedReturn' => 'handheld, only screen and (max-device-width: 480px)', - 'message' => 'With $wgHandheldForIPhone true, handheld media type is transformed' - ) ); - - $this->assertTransformCssMediaCase( array( - 'media' => 'handheld', - 'handheldForIPhone' => false, - 'expectedReturn' => 'handheld', - 'message' => 'With $wgHandheldForIPhone false, handheld media type is preserved' - ) ); } } diff --git a/tests/phpunit/includes/PathRouterTest.php b/tests/phpunit/includes/PathRouterTest.php index 22591873..adfb215a 100644 --- a/tests/phpunit/includes/PathRouterTest.php +++ b/tests/phpunit/includes/PathRouterTest.php @@ -1,10 +1,17 @@ <?php /** - * Tests for the PathRouter parsing + * Tests for the PathRouter parsing. + * + * @todo Add covers tags. */ class PathRouterTest extends MediaWikiTestCase { + /** + * @var PathRouter + */ + protected $basicRouter; + protected function setUp() { parent::setUp(); $router = new PathRouter; @@ -151,18 +158,20 @@ class PathRouterTest extends MediaWikiTestCase { $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 ) { + 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 ); } } @@ -251,5 +260,4 @@ class PathRouterTest extends MediaWikiTestCase { $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 index 7aa3c4a4..3dec2da0 100644 --- a/tests/phpunit/includes/PreferencesTest.php +++ b/tests/phpunit/includes/PreferencesTest.php @@ -4,11 +4,16 @@ * @group Database */ class PreferencesTest extends MediaWikiTestCase { - /** Array of User objects */ + /** + * @var User[] + */ private $prefUsers; + /** + * @var RequestContext + */ private $context; - function __construct() { + public function __construct() { parent::__construct(); $this->prefUsers['noemail'] = new User; @@ -30,14 +35,17 @@ class PreferencesTest extends MediaWikiTestCase { protected function setUp() { parent::setUp(); - $this->setMwGlobals( 'wgEnableEmail', true ); + $this->setMwGlobals( array( + 'wgEnableEmail' => true, + 'wgEmailAuthentication' => true, + ) ); } /** * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserHasNoEmail() { + public function testEmailFieldsWhenUserHasNoEmail() { $prefs = $this->prefsFor( 'noemail' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -49,7 +57,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailNotAuthenticated() { + public function testEmailFieldsWhenUserEmailNotAuthenticated() { $prefs = $this->prefsFor( 'notauth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -61,7 +69,7 @@ class PreferencesTest extends MediaWikiTestCase { * Placeholder to verify bug 34302 * @covers Preferences::profilePreferences */ - function testEmailFieldsWhenUserEmailIsAuthenticated() { + public function testEmailFieldsWhenUserEmailIsAuthenticated() { $prefs = $this->prefsFor( 'auth' ); $this->assertArrayHasKey( 'cssclass', $prefs['emailaddress'] @@ -70,13 +78,14 @@ class PreferencesTest extends MediaWikiTestCase { } /** Helper */ - function prefsFor( $user_key ) { + protected 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 948b6354..00000000 --- a/tests/phpunit/includes/Providers.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Generic providers for the MediaWiki PHPUnit test suite - * - * @author Antoine Musso - * @copyright Copyright © 2011, Antoine Musso - * @file - */ - -/** */ -class MediaWikiProvide { - - /* provide an array of numbers from 1 up to @param $num */ - private static function createProviderUpTo( $num ) { - $ret = array(); - for ( $i = 1; $i <= $num; $i++ ) { - $ret[] = array( $i ); - } - return $ret; - } - - /* array of months numbers (as an integer) */ - public static function Months() { - return self::createProviderUpTo( 12 ); - } - - /* array of days numbers (as an integer) */ - public static function Days() { - return self::createProviderUpTo( 31 ); - } - - public static function DaysMonths() { - $ret = array(); - - $months = self::Months(); - $days = self::Days(); - foreach ( $months as $month ) { - foreach ( $days as $day ) { - $ret[] = array( $day[0], $month[0] ); - } - } - return $ret; - } -} diff --git a/tests/phpunit/includes/RecentChangeTest.php b/tests/phpunit/includes/RecentChangeTest.php index a1e62363..cfa3e777 100644 --- a/tests/phpunit/includes/RecentChangeTest.php +++ b/tests/phpunit/includes/RecentChangeTest.php @@ -9,7 +9,7 @@ class RecentChangeTest extends MediaWikiTestCase { protected $user_comment; protected $context; - function __construct() { + public function __construct() { parent::__construct(); $this->title = Title::newFromText( 'SomeTitle' ); @@ -56,7 +56,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeBlock() { + public function testIrcMsgForLogTypeBlock() { $sep = $this->context->msg( 'colon-separator' )->text(); # block/block @@ -78,7 +78,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeDelete() { + public function testIrcMsgForLogTypeDelete() { $sep = $this->context->msg( 'colon-separator' )->text(); # delete/delete @@ -101,7 +101,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeNewusers() { + public function testIrcMsgForLogTypeNewusers() { $this->assertIRCComment( 'New user account', 'newusers', 'newusers', @@ -127,7 +127,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeMove() { + public function testIrcMsgForLogTypeMove() { $move_params = array( '4::target' => $this->target->getPrefixedText(), '5::noredir' => 0, @@ -154,7 +154,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypePatrol() { + public function testIrcMsgForLogTypePatrol() { # patrol/patrol $this->assertIRCComment( $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(), @@ -170,7 +170,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeProtect() { + public function testIrcMsgForLogTypeProtect() { $protectParams = array( '[edit=sysop] (indefinite) [move=sysop] (indefinite)' ); @@ -204,7 +204,7 @@ class RecentChangeTest extends MediaWikiTestCase { /** * @covers LogFormatter::getIRCActionText */ - function testIrcMsgForLogTypeUpload() { + public function testIrcMsgForLogTypeUpload() { $sep = $this->context->msg( 'colon-separator' )->text(); # upload/upload @@ -225,24 +225,24 @@ class RecentChangeTest extends MediaWikiTestCase { } /** - * @todo: Emulate these edits somehow and extract + * @todo Emulate these edits somehow and extract * raw edit summary from RecentChange object * -- */ /* - function testIrcMsgForBlankingAES() { + public function testIrcMsgForBlankingAES() { // $this->context->msg( 'autosumm-blank', .. ); } - function testIrcMsgForReplaceAES() { + public function testIrcMsgForReplaceAES() { // $this->context->msg( 'autosumm-replace', .. ); } - function testIrcMsgForRollbackAES() { + public function testIrcMsgForRollbackAES() { // $this->context->msg( 'revertpage', .. ); } - function testIrcMsgForUndoAES() { + public function testIrcMsgForUndoAES() { // $this->context->msg( 'undo-summary', .. ); } */ @@ -251,10 +251,11 @@ class RecentChangeTest extends MediaWikiTestCase { * @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 $params * @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 = '' ) { + protected function assertIRCComment( $expected, $type, $action, $params, $comment = null, $msg = '' ) { $logEntry = new ManualLogEntry( $type, $action ); $logEntry->setPerformer( $this->user ); @@ -267,8 +268,8 @@ class RecentChangeTest extends MediaWikiTestCase { $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() ); + // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment + $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() ); $this->assertEquals( $expected, @@ -276,5 +277,4 @@ class RecentChangeTest extends MediaWikiTestCase { $msg ); } - } diff --git a/tests/phpunit/includes/RequestContextTest.php b/tests/phpunit/includes/RequestContextTest.php index f5871716..1776b5d5 100644 --- a/tests/phpunit/includes/RequestContextTest.php +++ b/tests/phpunit/includes/RequestContextTest.php @@ -7,6 +7,8 @@ class RequestContextTest extends MediaWikiTestCase { /** * Test the relationship between title and wikipage in RequestContext + * @covers RequestContext::getWikiPage + * @covers RequestContext::getTitle */ public function testWikiPageTitle() { $context = new RequestContext(); @@ -25,9 +27,11 @@ class RequestContextTest extends MediaWikiTestCase { $context->setTitle( $curTitle ); $this->assertTrue( $curTitle->equals( $context->getWikiPage()->getTitle() ), "When a title is updated the WikiPage should be purged and recreated on-demand with the new title." ); - } + /** + * @covers RequestContext::importScopedSession + */ public function testImportScopedSession() { $context = RequestContext::getMain(); @@ -58,7 +62,7 @@ class RequestContextTest extends MediaWikiTestCase { $this->assertEquals( $sinfo['userId'], $context->getUser()->getId(), "Correct context user ID." ); $this->assertEquals( 'UnitTestContextUser', $context->getUser()->getName(), "Correct context user name." ); - unset ( $sc ); // restore previous context + unset( $sc ); // restore previous context $info = $context->exportSession(); $this->assertEquals( $oInfo['ip'], $info['ip'], "Correct initial IP address." ); diff --git a/tests/phpunit/includes/ResourceLoaderTest.php b/tests/phpunit/includes/ResourceLoaderTest.php index 60618b10..ca8b2b6e 100644 --- a/tests/phpunit/includes/ResourceLoaderTest.php +++ b/tests/phpunit/includes/ResourceLoaderTest.php @@ -4,6 +4,32 @@ class ResourceLoaderTest extends MediaWikiTestCase { protected static $resourceLoaderRegisterModulesHook; + protected function setUp() { + parent::setUp(); + + // $wgResourceLoaderLESSFunctions, $wgResourceLoaderLESSImportPaths; $wgResourceLoaderLESSVars; + + $this->setMwGlobals( array( + 'wgResourceLoaderLESSFunctions' => array( + 'test-sum' => function ( $frame, $less ) { + $sum = 0; + foreach ( $frame[2] as $arg ) { + $sum += (int)$arg[1]; + } + return $sum; + }, + ), + 'wgResourceLoaderLESSImportPaths' => array( + dirname( __DIR__ ) . '/data/less/common', + ), + 'wgResourceLoaderLESSVars' => array( + 'foo' => '2px', + 'Foo' => '#eeeeee', + 'bar' => 5, + ), + ) ); + } + /* Hook Methods */ /** @@ -11,6 +37,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { */ public static function resourceLoaderRegisterModules( &$resourceLoader ) { self::$resourceLoaderRegisterModulesHook = true; + return true; } @@ -21,6 +48,14 @@ class ResourceLoaderTest extends MediaWikiTestCase { ); } + public static function provideResourceLoaderContext() { + $resourceLoader = new ResourceLoader(); + $request = new FauxRequest(); + return array( + array( new ResourceLoaderContext( $resourceLoader, $request ) ), + ); + } + /* Test Methods */ /** @@ -31,6 +66,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { self::$resourceLoaderRegisterModulesHook = false; $resourceLoader = new ResourceLoader(); $this->assertTrue( self::$resourceLoaderRegisterModulesHook ); + return $resourceLoader; } @@ -48,7 +84,22 @@ class ResourceLoaderTest extends MediaWikiTestCase { } /** + * @dataProvider provideResourceLoaderContext + * @covers ResourceLoaderFileModule::compileLessFile + */ + public function testLessFileCompilation( $context ) { + $basePath = __DIR__ . '/../data/less/module'; + $module = new ResourceLoaderFileModule( array( + 'localBasePath' => $basePath, + 'styles' => array( 'styles.less' ), + ) ); + $styles = $module->getStyles( $context ); + $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] ); + } + + /** * @dataProvider providePackedModules + * @covers ResourceLoader::makePackedModulesString */ public function testMakePackedModulesString( $desc, $modules, $packed ) { $this->assertEquals( $packed, ResourceLoader::makePackedModulesString( $modules ), $desc ); @@ -56,6 +107,7 @@ class ResourceLoaderTest extends MediaWikiTestCase { /** * @dataProvider providePackedModules + * @covers ResourceLoaderContext::expandModuleNames */ public function testexpandModuleNames( $desc, $modules, $packed ) { $this->assertEquals( $modules, ResourceLoaderContext::expandModuleNames( $packed ), $desc ); @@ -77,14 +129,20 @@ class ResourceLoaderTest extends MediaWikiTestCase { 'Regression fixed in r88706 with dotless names', array( 'foo', 'bar', 'baz' ), 'foo,bar,baz', - ) + ), + array( + 'Prefixless modules after a prefixed module', + array( 'single.module', 'foobar', 'foobaz' ), + 'single.module|foobar,foobaz', + ), ); } } /* Stubs */ -class ResourceLoaderTestModule extends ResourceLoaderModule {} +class ResourceLoaderTestModule extends ResourceLoaderModule { +} /* Hooks */ global $wgHooks; diff --git a/tests/phpunit/includes/RevisionStorageTest.php b/tests/phpunit/includes/RevisionStorageTest.php index e8d8db0a..e17c7b0f 100644 --- a/tests/phpunit/includes/RevisionStorageTest.php +++ b/tests/phpunit/includes/RevisionStorageTest.php @@ -17,7 +17,7 @@ class RevisionStorageTest extends MediaWikiTestCase { */ var $the_page; - function __construct( $name = null, array $data = array(), $dataName = '' ) { + function __construct( $name = null, array $data = array(), $dataName = '' ) { parent::__construct( $name, $data, $dataName ); $this->tablesUsed = array_merge( $this->tablesUsed, @@ -38,7 +38,7 @@ class RevisionStorageTest extends MediaWikiTestCase { 'iwlinks' ) ); } - public function setUp() { + protected function setUp() { global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang; parent::setUp(); @@ -365,7 +365,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page = $this->createPage( 'RevisionStorageTest_testIsCurrent', 'Lorem Ipsum', CONTENT_MODEL_WIKITEXT ); $rev1 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev1->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -374,7 +374,7 @@ class RevisionStorageTest extends MediaWikiTestCase { $page->doEditContent( ContentHandler::makeContent( 'Bla bla', $page->getTitle(), CONTENT_MODEL_WIKITEXT ), 'second rev' ); $rev2 = $page->getRevision(); - # @todo: find out if this should be true + # @todo find out if this should be true # $this->assertTrue( $rev2->isCurrent() ); $rev1x = Revision::newFromId( $rev1->getId() ); @@ -456,15 +456,15 @@ class RevisionStorageTest extends MediaWikiTestCase { * @dataProvider provideUserWasLastToEdit */ public function testUserWasLastToEdit( $sinceIdx, $expectedLast ) { - $userA = \User::newFromName( "RevisionStorageTest_userA" ); - $userB = \User::newFromName( "RevisionStorageTest_userB" ); + $userA = User::newFromName( "RevisionStorageTest_userA" ); + $userB = User::newFromName( "RevisionStorageTest_userB" ); if ( $userA->getId() === 0 ) { - $userA = \User::createNew( $userA->getName() ); + $userA = User::createNew( $userA->getName() ); } if ( $userB->getId() === 0 ) { - $userB = \User::createNew( $userB->getName() ); + $userB = User::createNew( $userB->getName() ); } $ns = $this->getDefaultWikitextNS(); diff --git a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php index 3948e345..4e83e355 100644 --- a/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php +++ b/tests/phpunit/includes/RevisionStorageTest_ContentHandlerUseDB.php @@ -6,14 +6,9 @@ * ^--- important, causes temporary tables to be used instead of the real database */ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { - var $saveContentHandlerNoDB = null; - function setUp() { - global $wgContentHandlerUseDB; - - $this->saveContentHandlerNoDB = $wgContentHandlerUseDB; - - $wgContentHandlerUseDB = false; + protected function setUp() { + $this->setMwGlobals( 'wgContentHandlerUseDB', false ); $dbw = wfGetDB( DB_MASTER ); @@ -32,14 +27,6 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { parent::setUp(); } - function tearDown() { - global $wgContentHandlerUseDB; - - parent::tearDown(); - - $wgContentHandlerUseDB = $this->saveContentHandlerNoDB; - } - /** * @covers Revision::selectFields */ @@ -76,7 +63,7 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { */ public function testGetContentFormat() { try { - //@todo: change this to test failure on using a non-standard (but supported) format + // @todo change this to test failure on using a non-standard (but supported) format // for a content model supported in the given location. As of 1.21, there are // no alternative formats for any of the standard content models that could be // used for this though. @@ -91,5 +78,4 @@ class RevisionTest_ContentHandlerUseDB extends RevisionStorageTest { $this->assertTrue( true ); // ok } } - } diff --git a/tests/phpunit/includes/RevisionTest.php b/tests/phpunit/includes/RevisionTest.php index db0245b9..b5819ff6 100644 --- a/tests/phpunit/includes/RevisionTest.php +++ b/tests/phpunit/includes/RevisionTest.php @@ -54,7 +54,10 @@ class RevisionTest extends MediaWikiTestCase { parent::tearDown(); } - function testGetRevisionText() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionText() { $row = new stdClass; $row->old_flags = ''; $row->old_text = 'This is a bunch of revision text.'; @@ -63,7 +66,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -74,7 +80,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Native() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Native() { $row = new stdClass; $row->old_flags = 'utf-8'; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -84,7 +93,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8Legacy() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8Legacy() { $row = new stdClass; $row->old_flags = ''; $row->old_text = "Wiki est l'\xe9cole superieur !"; @@ -94,7 +106,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8NativeGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8NativeGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -106,7 +121,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testGetRevisionTextUtf8LegacyGzip() { + /** + * @covers Revision::getRevisionText + */ + public function testGetRevisionTextUtf8LegacyGzip() { $this->checkPHPExtension( 'zlib' ); $row = new stdClass; @@ -118,7 +136,10 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ) ); } - function testCompressRevisionTextUtf8() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8() { $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; $row->old_flags = Revision::compressRevisionText( $row->old_text ); @@ -132,11 +153,12 @@ class RevisionTest extends MediaWikiTestCase { Revision::getRevisionText( $row ), "getRevisionText" ); } - function testCompressRevisionTextUtf8Gzip() { + /** + * @covers Revision::compressRevisionText + */ + public function testCompressRevisionTextUtf8Gzip() { $this->checkPHPExtension( 'zlib' ); - - global $wgCompressRevisions; - $wgCompressRevisions = true; + $this->setMwGlobals( 'wgCompressRevisions', true ); $row = new stdClass; $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; @@ -157,6 +179,8 @@ class RevisionTest extends MediaWikiTestCase { * @param string $text * @param string $title * @param string $model + * @param null $format + * * @return Revision */ function newTestRevision( $text, $title = "Test", $model = CONTENT_MODEL_WIKITEXT, $format = null ) { @@ -196,8 +220,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentModel + * @covers Revision::getContentModel */ - function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { + public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedModel, $rev->getContentModel() ); @@ -216,8 +241,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentFormat + * @covers Revision::getContentFormat */ - function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { + public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedFormat, $rev->getContentFormat() ); @@ -235,8 +261,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContentHandler + * @covers Revision::getContentHandler */ - function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { + public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) ); @@ -254,8 +281,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetContent + * @covers Revision::getContent */ - function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { + public function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) { $rev = $this->newTestRevision( $text, $title, $model, $format ); $content = $rev->getContent( $audience ); @@ -274,8 +302,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getText */ - function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -286,8 +315,9 @@ class RevisionTest extends MediaWikiTestCase { /** * @group Database * @dataProvider dataGetText + * @covers Revision::getRawText */ - function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { + public function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) { $this->hideDeprecated( 'Revision::getRawText' ); $rev = $this->newTestRevision( $text, $title, $model, $format ); @@ -330,6 +360,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( $expected_hash, $rev->getSha1() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithText() { $this->hideDeprecated( "Revision::getText" ); @@ -344,6 +377,9 @@ class RevisionTest extends MediaWikiTestCase { $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() ); } + /** + * @covers Revision::__construct + */ public function testConstructWithContent() { $this->hideDeprecated( "Revision::getText" ); @@ -363,8 +399,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns a clone when needed. * * @group Database + * @covers Revision::getContent */ - function testGetContentClone() { + public function testGetContentClone() { $content = new RevisionTestModifyableContent( "foo" ); $rev = new Revision( @@ -396,8 +433,9 @@ class RevisionTest extends MediaWikiTestCase { * Tests whether $rev->getContent() returns the same object repeatedly if appropriate. * * @group Database + * @covers Revision::getContent */ - function testGetContentUncloned() { + public function testGetContentUncloned() { $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT ); $content = $rev->getContent( Revision::RAW ); $content2 = $rev->getContent( Revision::RAW ); @@ -405,7 +443,6 @@ class RevisionTest extends MediaWikiTestCase { // for immutable content like wikitext, this should be the same object $this->assertSame( $content, $content2 ); } - } class RevisionTestModifyableContent extends TextContent { @@ -424,7 +461,6 @@ class RevisionTestModifyableContent extends TextContent { public function setText( $text ) { $this->mText = $text; } - } class RevisionTestModifyableContentHandler extends TextContentHandler { diff --git a/tests/phpunit/includes/SampleTest.php b/tests/phpunit/includes/SampleTest.php index 8a881915..8516a4ce 100644 --- a/tests/phpunit/includes/SampleTest.php +++ b/tests/phpunit/includes/SampleTest.php @@ -33,7 +33,7 @@ class TestSample extends MediaWikiLangTestCase { * "Agile Documentation" at * http://www.phpunit.de/manual/3.4/en/other-uses-for-tests.html */ - function testTitleObjectStringConversion() { + public function testTitleObjectStringConversion() { $title = Title::newFromText( "text" ); $this->assertInstanceOf( 'Title', $title, "Title creation" ); $this->assertEquals( "Text", $title, "Automatic string conversion" ); @@ -98,7 +98,7 @@ class TestSample extends MediaWikiLangTestCase { * @expectedException MWException object * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.expectedException */ - function testTitleObjectFromObject() { + public 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 index c0ed4a59..81246d33 100644 --- a/tests/phpunit/includes/SanitizerTest.php +++ b/tests/phpunit/includes/SanitizerTest.php @@ -1,5 +1,9 @@ <?php +/** + * @todo Tests covering decodeCharReferences can be refactored into a single + * method and dataprovider. + */ class SanitizerTest extends MediaWikiTestCase { protected function setUp() { @@ -8,7 +12,10 @@ class SanitizerTest extends MediaWikiTestCase { AutoLoader::loadClass( 'Sanitizer' ); } - function testDecodeNamedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNamedEntities() { $this->assertEquals( "\xc3\xa9cole", Sanitizer::decodeCharReferences( 'école' ), @@ -16,7 +23,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeNumericEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeNumericEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -24,7 +34,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole!", Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), @@ -32,7 +45,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testDecodeMixedComplexEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testDecodeMixedComplexEntities() { $this->assertEquals( "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", Sanitizer::decodeCharReferences( @@ -42,7 +58,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidAmpersand() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidAmpersand() { $this->assertEquals( 'a & b', Sanitizer::decodeCharReferences( 'a & b' ), @@ -50,7 +69,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidEntities() { $this->assertEquals( '&foo;', Sanitizer::decodeCharReferences( '&foo;' ), @@ -58,7 +80,10 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testInvalidNumberedEntities() { + /** + * @covers Sanitizer::decodeCharReferences + */ + public function testInvalidNumberedEntities() { $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); } @@ -69,10 +94,8 @@ class SanitizerTest extends MediaWikiTestCase { * @param String $tag Name of an HTML5 element (ie: 'video') * @param Boolean $escaped Wheter sanitizer let the tag in or escape it (ie: '<video>') */ - function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { + public function testRemovehtmltagsOnHtml5Tags( $tag, $escaped ) { $this->setMwGlobals( array( - # Enable HTML5 mode - 'wgHtml5' => true, 'wgUseTidy' => false ) ); @@ -90,7 +113,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Provide HTML5 tags */ - function provideHtml5Tags() { + public static function provideHtml5Tags() { $ESCAPED = true; # We want tag to be escaped $VERBATIM = false; # We want to keep the tag return array( @@ -101,31 +124,57 @@ class SanitizerTest extends MediaWikiTestCase { ); } - function testSelfClosingTag() { - $this->setMwGlobals( array( - 'wgUseTidy' => false - ) ); - - $this->assertEquals( - '<div>Hello world</div>', - Sanitizer::removeHTMLtags( '<div>Hello world</div />' ), - 'Self-closing closing div' + function dataRemoveHTMLtags() { + return array( + // former testSelfClosingTag + array( + '<div>Hello world</div />', + '<div>Hello world</div>', + 'Self-closing closing div' + ), + // Make sure special nested HTML5 semantics are not broken + // http://www.whatwg.org/html/text-level-semantics.html#the-kbd-element + array( + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + '<kbd><kbd>Shift</kbd>+<kbd>F3</kbd></kbd>', + 'Nested <kbd>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-sub-and-sup-elements + array( + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + '<var>x<sub><var>i</var></sub></var>, <var>y<sub><var>i</var></sub></var>', + 'Nested <var>.' + ), + // http://www.whatwg.org/html/text-level-semantics.html#the-dfn-element + array( + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<dfn><abbr title="Garage Door Opener">GDO</abbr></dfn>', + '<abbr> inside <dfn>', + ), ); } + /** + * @dataProvider dataRemoveHTMLtags + * @covers Sanitizer::removeHTMLtags + */ + public function testRemoveHTMLtags( $input, $output, $msg = null ) { + $GLOBALS['wgUseTidy'] = false; + $this->assertEquals( $output, Sanitizer::removeHTMLtags( $input ), $msg ); + } /** * @dataProvider provideTagAttributesToDecode * @covers Sanitizer::decodeTagAttributes */ - function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { + public function testDecodeTagAttributes( $expected, $attributes, $message = '' ) { $this->assertEquals( $expected, Sanitizer::decodeTagAttributes( $attributes ), $message ); } - function provideTagAttributesToDecode() { + public static function provideTagAttributesToDecode() { return array( array( array( 'foo' => 'bar' ), 'foo=bar', 'Unquoted attribute' ), array( array( 'foo' => 'bar' ), ' foo = bar ', 'Spaced attribute' ), @@ -148,7 +197,6 @@ class SanitizerTest extends MediaWikiTestCase { array( array( 'foo.' => 'baz' ), 'foo.=baz', 'A . is allowed as last character' ), array( array( 'foo6' => 'baz' ), 'foo6=baz', 'Numbers are allowed' ), - # This bit is more relaxed than XML rules, but some extensions use # it, like ProofreadPage (see bug 27539) array( array( '1foo' => 'baz' ), '1foo=baz', 'Leading numbers are allowed' ), @@ -167,7 +215,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideDeprecatedAttributes * @covers Sanitizer::fixTagAttributes */ - function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { + public function testDeprecatedAttributesUnaltered( $inputAttr, $inputEl, $message = '' ) { $this->assertEquals( " $inputAttr", Sanitizer::fixTagAttributes( $inputAttr, $inputEl ), $message @@ -195,7 +243,7 @@ class SanitizerTest extends MediaWikiTestCase { * @dataProvider provideCssCommentsFixtures * @covers Sanitizer::checkCss */ - function testCssCommentsChecking( $expected, $css, $message = '' ) { + public function testCssCommentsChecking( $expected, $css, $message = '' ) { $this->assertEquals( $expected, Sanitizer::checkCss( $css ), $message @@ -205,10 +253,14 @@ class SanitizerTest extends MediaWikiTestCase { public static function provideCssCommentsFixtures() { /** array( <expected>, <css>, [message] ) */ return array( - array( ' ', '/**/' ), + // Valid comments spanning entire input + array( '/**/', '/**/' ), + array( '/* comment */', '/* comment */' ), + // Weird stuff array( ' ', '/****/' ), - array( ' ', '/* comment */' ), - array( ' ', "\\2f\\2a foo \\2a\\2f", + array( ' ', '/* /* */' ), + array( 'display: block;', "display:/* foo */block;" ), + array( 'display: block;', "display:\\2f\\2a foo \\2a\\2f block;", 'Backslash-escaped comments must be stripped (bug 28450)' ), array( '', '/* unfinished comment structure', 'Remove anything after a comment-start token' ), @@ -229,7 +281,7 @@ class SanitizerTest extends MediaWikiTestCase { /** * Test for support or lack of support for specific attributes in the attribute whitelist. */ - function provideAttributeSupport() { + public static function provideAttributeSupport() { /** array( <attributes>, <expected>, <message> ) */ return array( array( 'div', ' role="presentation"', ' role="presentation"', 'Support for WAI-ARIA\'s role="presentation".' ), @@ -239,12 +291,12 @@ class SanitizerTest extends MediaWikiTestCase { /** * @dataProvider provideAttributeSupport + * @covers Sanitizer::fixTagAttributes */ - function testAttributeSupport( $tag, $attributes, $expected, $message ) { + public function testAttributeSupport( $tag, $attributes, $expected, $message ) { $this->assertEquals( $expected, Sanitizer::fixTagAttributes( $attributes, $tag ), $message ); } - } diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php index fe0bc64e..f13e8382 100644 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ b/tests/phpunit/includes/SanitizerValidateEmailTest.php @@ -1,5 +1,10 @@ <?php +/** + * @covers Sanitizer::validateEmail + * @TODO all test methods in this class should be refactored and... + * use a single test method and a single data provider... + */ class SanitizerValidateEmailTest extends MediaWikiTestCase { private function checkEmail( $addr, $expected = true, $msg = '' ) { @@ -22,54 +27,56 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->checkEmail( $addr, false, $msg ); } - function testEmailWellKnownUserAtHostDotTldAreValid() { + public function testEmailWellKnownUserAtHostDotTldAreValid() { $this->valid( 'user@example.com' ); $this->valid( 'user@example.museum' ); } - function testEmailWithUpperCaseCharactersAreValid() { + public function testEmailWithUpperCaseCharactersAreValid() { $this->valid( 'USER@example.com' ); $this->valid( 'user@EXAMPLE.COM' ); $this->valid( 'user@Example.com' ); $this->valid( 'USER@eXAMPLE.com' ); } - function testEmailWithAPlusInUserName() { + public function testEmailWithAPlusInUserName() { $this->valid( 'user+sub@example.com' ); $this->valid( 'user+@example.com' ); } - function testEmailDoesNotNeedATopLevelDomain() { + public function testEmailDoesNotNeedATopLevelDomain() { $this->valid( "user@localhost" ); $this->valid( "FooBar@localdomain" ); $this->valid( "nobody@mycompany" ); } - function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { + public 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() { + public 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() { + /** + * bug 26948 : comma were matched by an incorrect regexp range + */ + public function testEmailWithCommasAreInvalids() { $this->invalid( "user,foo@example.org" ); $this->invalid( "userfoo@ex,ample.org" ); } - function testEmailWithHyphens() { + public function testEmailWithHyphens() { $this->valid( "user-foo@example.org" ); $this->valid( "userfoo@ex-ample.org" ); } - function testEmailDomainCanNotBeginWithDot() { + public function testEmailDomainCanNotBeginWithDot() { $this->invalid( "user@." ); $this->invalid( "user@.localdomain" ); $this->invalid( "user@localdomain." ); @@ -78,19 +85,19 @@ class SanitizerValidateEmailTest extends MediaWikiTestCase { $this->invalid( ".@a............" ); } - function testEmailWithFunnyCharacters() { + public function testEmailWithFunnyCharacters() { $this->valid( "\$user!ex{this}@123.com" ); } - function testEmailTopLevelDomainCanBeNumerical() { + public function testEmailTopLevelDomainCanBeNumerical() { $this->valid( "user@example.1234" ); } - function testEmailWithoutAtSignIsInvalid() { + public function testEmailWithoutAtSignIsInvalid() { $this->invalid( 'useràexample.com' ); } - function testEmailWithOneCharacterDomainIsValid() { + public 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 3422c90c..00000000 --- a/tests/phpunit/includes/SeleniumConfigurationTest.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php - -class SeleniumConfigurationTest extends MediaWikiTestCase { - - /** - * The file where the test temporarity stores the selenium config. - * This should be cleaned up as part of teardown. - */ - private $tempFileName; - - /** - * String containing the a sample selenium settings - */ - private $testConfig0 = ' -[SeleniumSettings] -browsers[firefox] = "*firefox" -browsers[iexplorer] = "*iexploreproxy" -browsers[chrome] = "*chrome" -host = "localhost" -port = "foobarr" -wikiUrl = "http://localhost/deployment" -username = "xxxxxxx" -userPassword = "" -testBrowser = "chrome" -startserver = -stopserver = -jUnitLogFile = -runAgainstGrid = false - -[SeleniumTests] -testSuite[SimpleSeleniumTestSuite] = "tests/selenium/SimpleSeleniumTestSuite.php" -testSuite[TestSuiteName] = "testSuitePath" -'; - /** - * Array of expected browsers from $testConfig0 - */ - private $testBrowsers0 = array( 'firefox' => '*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', |