diff options
Diffstat (limited to 'tests')
420 files changed, 90195 insertions, 0 deletions
diff --git a/tests/.htaccess b/tests/.htaccess new file mode 100644 index 00000000..3a428827 --- /dev/null +++ b/tests/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/tests/TestsAutoLoader.php b/tests/TestsAutoLoader.php new file mode 100644 index 00000000..00ce13c8 --- /dev/null +++ b/tests/TestsAutoLoader.php @@ -0,0 +1,104 @@ +<?php +/** + * AutoLoader for the testing suite. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + * @ingroup Testing + */ + +global $wgAutoloadClasses; +$testDir = __DIR__; + +$wgAutoloadClasses += array( + + # tests + '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", + 'TestUser' => "$testDir/phpunit/includes/TestUser.php", + + # tests/phpunit/includes + 'BlockTest' => "$testDir/phpunit/includes/BlockTest.php", + 'RevisionStorageTest' => "$testDir/phpunit/includes/RevisionStorageTest.php", + 'WikiPageTest' => "$testDir/phpunit/includes/WikiPageTest.php", + + //db + 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php", + 'PageORMTableForTesting' => "$testDir/phpunit/includes/db/ORMTableTest.php", + 'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php", + + # tests/phpunit/includes/api + 'ApiFormatTestBase' => "$testDir/phpunit/includes/api/format/ApiFormatTestBase.php", + 'ApiTestCase' => "$testDir/phpunit/includes/api/ApiTestCase.php", + 'ApiTestContext' => "$testDir/phpunit/includes/api/ApiTestCase.php", + 'MockApi' => "$testDir/phpunit/includes/api/ApiTestCase.php", + 'RandomImageGenerator' => "$testDir/phpunit/includes/api/RandomImageGenerator.php", + 'UserWrapper' => "$testDir/phpunit/includes/api/ApiTestCase.php", + + # tests/phpunit/includes/content + 'DummyContentHandlerForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php", + 'DummyContentForTesting' => "$testDir/phpunit/includes/content/ContentHandlerTest.php", + 'ContentHandlerTest' => "$testDir/phpunit/includes/content/ContentHandlerTest.php", + 'JavaScriptContentTest' => "$testDir/phpunit/includes/content/JavaScriptContentTest.php", + 'TextContentTest' => "$testDir/phpunit/includes/content/TextContentTest.php", + 'WikitextContentTest' => "$testDir/phpunit/includes/content/WikitextContentTest.php", + + # tests/phpunit/includes/db + 'ORMRowTest' => "$testDir/phpunit/includes/db/ORMRowTest.php", + + # 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", + + # tests/phpunit/maintenance + 'DumpTestCase' => "$testDir/phpunit/maintenance/DumpTestCase.php", + + # tests/parser + 'ParserTest' => "$testDir/parser/parserTest.inc", + 'ParserTestParserHook' => "$testDir/parser/parserTestsParserHook.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/README b/tests/parser/README new file mode 100644 index 00000000..8b413376 --- /dev/null +++ b/tests/parser/README @@ -0,0 +1,8 @@ +Parser tests are run using our PHPUnit test suite in tests/phpunit: + + $ cd tests/phpunit + ./phpunit.php --group Parser + +You can optionally filter by title using --regex. I.e. : + + ./phpunit.php --group Parser --regex="Bug 6200" diff --git a/tests/parser/extraParserTests.txt b/tests/parser/extraParserTests.txt Binary files differnew file mode 100644 index 00000000..bef8f506 --- /dev/null +++ b/tests/parser/extraParserTests.txt diff --git a/tests/parser/parserTest.inc b/tests/parser/parserTest.inc new file mode 100644 index 00000000..58ea1ed0 --- /dev/null +++ b/tests/parser/parserTest.inc @@ -0,0 +1,1465 @@ +<?php +/** + * 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/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @todo Make this more independent of the configuration (and if possible the database) + * @todo document + * @file + * @ingroup Testing + */ + +/** + * @ingroup Testing + */ +class ParserTest { + /** + * @var bool $color whereas output should be colorized + */ + private $color; + + /** + * @var bool $showOutput Show test output + */ + private $showOutput; + + /** + * @var bool $useTemporaryTables Use temporary tables for the temporary database + */ + private $useTemporaryTables = true; + + /** + * @var bool $databaseSetupDone True if the database has been set up + */ + private $databaseSetupDone = false; + + /** + * Our connection to the database + * @var DatabaseBase + */ + private $db; + + /** + * Database clone helper + * @var CloneDatabase + */ + private $dbClone; + + /** + * @var string $oldTablePrefix Original table prefix + */ + private $oldTablePrefix; + + private $maxFuzzTestLength = 300; + private $fuzzSeed = 0; + private $memoryLimit = 50; + private $uploadDir = null; + + public $regex = ""; + private $savedGlobals = array(); + + /** + * Sets terminal colorization and diff/quick modes depending on OS and + * command-line options (--color and --quick). + */ + public function __construct( $options = array() ) { + # Only colorize output if stdout is a terminal. + $this->color = !wfIsWindows() && Maintenance::posix_isatty( 1 ); + + if ( isset( $options['color'] ) ) { + switch ( $options['color'] ) { + case 'no': + $this->color = false; + break; + case 'yes': + default: + $this->color = true; + break; + } + } + + $this->term = $this->color + ? new AnsiTermColorer() + : new DummyTermColorer(); + + $this->showDiffs = !isset( $options['quick'] ); + $this->showProgress = !isset( $options['quiet'] ); + $this->showFailure = !( + isset( $options['quiet'] ) + && ( isset( $options['record'] ) + || isset( $options['compare'] ) ) ); // redundant output + + $this->showOutput = isset( $options['show-output'] ); + + if ( isset( $options['filter'] ) ) { + $options['regex'] = $options['filter']; + } + + if ( isset( $options['regex'] ) ) { + if ( isset( $options['record'] ) ) { + echo "Warning: --record cannot be used with --regex, disabling --record\n"; + unset( $options['record'] ); + } + $this->regex = $options['regex']; + } else { + # Matches anything + $this->regex = ''; + } + + $this->setupRecorder( $options ); + $this->keepUploads = isset( $options['keep-uploads'] ); + + if ( isset( $options['seed'] ) ) { + $this->fuzzSeed = intval( $options['seed'] ) - 1; + } + + $this->runDisabled = isset( $options['run-disabled'] ); + $this->runParsoid = isset( $options['run-parsoid'] ); + + $this->hooks = array(); + $this->functionHooks = array(); + self::setUp(); + } + + static function setUp() { + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, + $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, + $wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, + $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, + $wgArticlePath, $wgScript, $wgStylePath, $wgExtensionAssetsPath, + $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers; + + $wgScript = '/index.php'; + $wgScriptPath = '/'; + $wgArticlePath = '/wiki/$1'; + $wgStylePath = '/skins'; + $wgExtensionAssetsPath = '/extensions'; + $wgThumbnailScriptPath = false; + $wgLockManagers = array( array( + 'name' => 'fsLockManager', + 'class' => 'FSLockManager', + 'lockDirectory' => wfTempDir() . '/test-repo/lockdir', + ), array( + 'name' => 'nullLockManager', + 'class' => 'NullLockManager', + ) ); + $wgLocalFileRepo = array( + 'class' => 'LocalRepo', + 'name' => 'local', + 'url' => 'http://example.com/images', + 'hashLevels' => 2, + 'transformVia404' => false, + 'backend' => new FSFileBackend( array( + 'name' => 'local-backend', + 'lockManager' => 'fsLockManager', + 'containerPaths' => array( + 'local-public' => wfTempDir() . '/test-repo/public', + 'local-thumb' => wfTempDir() . '/test-repo/thumb', + 'local-temp' => wfTempDir() . '/test-repo/temp', + 'local-deleted' => wfTempDir() . '/test-repo/deleted', + ) + ) ) + ); + $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; + $wgNamespaceAliases['Image'] = NS_FILE; + $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + # 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 ) { + $wgMainCacheType = CACHE_NONE; + } + if ( $wgMessageCacheType === CACHE_DB ) { + $wgMessageCacheType = CACHE_NONE; + } + if ( $wgParserCacheType === CACHE_DB ) { + $wgParserCacheType = CACHE_NONE; + } + + $wgEnableParserCache = false; + DeferredUpdates::clearPendingUpdates(); + $wgMemc = wfGetMainCache(); // checks $wgMainCacheType + $messageMemc = wfGetMessageCacheStorage(); + $parserMemc = wfGetParserCacheStorage(); + + // $wgContLang = new StubContLang; + $wgUser = new User; + $context = new RequestContext; + $wgLang = $context->getLanguage(); + $wgOut = $context->getOutput(); + $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); + $wgRequest = $context->getRequest(); + + if ( $wgStyleDirectory === false ) { + $wgStyleDirectory = "$IP/skins"; + } + + 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 ) { + if ( isset( $options['record'] ) ) { + $this->recorder = new DbTestRecorder( $this ); + $this->recorder->version = isset( $options['setversion'] ) ? + $options['setversion'] : SpecialVersion::getVersion(); + } elseif ( isset( $options['compare'] ) ) { + $this->recorder = new DbTestPreviewer( $this ); + } else { + $this->recorder = new TestRecorder( $this ); + } + } + + /** + * Remove last character if it is a newline + * @group utility + */ + public static function chomp( $s ) { + if ( substr( $s, -1 ) === "\n" ) { + return substr( $s, 0, -1 ); + } else { + return $s; + } + } + + /** + * Run a fuzz test series + * Draw input from a set of test files + */ + function fuzzTest( $filenames ) { + $GLOBALS['wgContLang'] = Language::factory( 'en' ); + $dict = $this->getFuzzInput( $filenames ); + $dictSize = strlen( $dict ); + $logMaxLength = log( $this->maxFuzzTestLength ); + $this->setupDatabase(); + ini_set( 'memory_limit', $this->memoryLimit * 1048576 ); + + $numTotal = 0; + $numSuccess = 0; + $user = new User; + $opts = ParserOptions::newFromUser( $user ); + $title = Title::makeTitle( NS_MAIN, 'Parser_test' ); + + while ( true ) { + // Generate test input + mt_srand( ++$this->fuzzSeed ); + $totalLength = mt_rand( 1, $this->maxFuzzTestLength ); + $input = ''; + + while ( strlen( $input ) < $totalLength ) { + $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength; + $hairLength = min( intval( exp( $logHairLength ) ), $dictSize ); + $offset = mt_rand( 0, $dictSize - $hairLength ); + $input .= substr( $dict, $offset, $hairLength ); + } + + $this->setupGlobals(); + $parser = $this->getParser(); + + // Run the test + try { + $parser->parse( $input, $title, $opts ); + $fail = false; + } catch ( Exception $exception ) { + $fail = true; + } + + if ( $fail ) { + echo "Test failed with seed {$this->fuzzSeed}\n"; + echo "Input:\n"; + printf( "string(%d) \"%s\"\n\n", strlen( $input ), $input ); + echo "$exception\n"; + } else { + $numSuccess++; + } + + $numTotal++; + $this->teardownGlobals(); + $parser->__destruct(); + + if ( $numTotal % 100 == 0 ) { + $usage = intval( memory_get_usage( true ) / $this->memoryLimit / 1048576 * 100 ); + echo "{$this->fuzzSeed}: $numSuccess/$numTotal (mem: $usage%)\n"; + if ( $usage > 90 ) { + echo "Out of memory:\n"; + $memStats = $this->getMemoryBreakdown(); + + foreach ( $memStats as $name => $usage ) { + echo "$name: $usage\n"; + } + $this->abort(); + } + } + } + } + + /** + * Get an input dictionary from a set of parser test files + */ + function getFuzzInput( $filenames ) { + $dict = ''; + + foreach ( $filenames as $filename ) { + $contents = file_get_contents( $filename ); + preg_match_all( '/!!\s*input\n(.*?)\n!!\s*result/s', $contents, $matches ); + + foreach ( $matches[1] as $match ) { + $dict .= $match . "\n"; + } + } + + return $dict; + } + + /** + * Get a memory usage breakdown + */ + function getMemoryBreakdown() { + $memStats = array(); + + foreach ( $GLOBALS as $name => $value ) { + $memStats['$' . $name] = strlen( serialize( $value ) ); + } + + $classes = get_declared_classes(); + + foreach ( $classes as $class ) { + $rc = new ReflectionClass( $class ); + $props = $rc->getStaticProperties(); + $memStats[$class] = strlen( serialize( $props ) ); + $methods = $rc->getMethods(); + + foreach ( $methods as $method ) { + $memStats[$class] += strlen( serialize( $method->getStaticVariables() ) ); + } + } + + $functions = get_defined_functions(); + + foreach ( $functions['user'] as $function ) { + $rf = new ReflectionFunction( $function ); + $memStats["$function()"] = strlen( serialize( $rf->getStaticVariables() ) ); + } + + asort( $memStats ); + + return $memStats; + } + + function abort() { + $this->abort(); + } + + /** + * Run a series of tests listed in the given text files. + * Each test consists of a brief description, wikitext input, + * and the expected HTML output. + * + * Prints status updates on stdout and counts up the total + * number and percentage of passed tests. + * + * @param $filenames Array of strings + * @return Boolean: true if passed all tests, false if any tests failed. + */ + public function runTestsFromFiles( $filenames ) { + $ok = false; + + // 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(); + $ok = true; + + foreach ( $filenames as $filename ) { + $tests = new TestFileIterator( $filename, $this ); + $ok = $this->runTests( $tests ) && $ok; + } + + $this->teardownDatabase(); + $this->recorder->report(); + } catch ( DBError $e ) { + echo $e->getMessage(); + } + $this->recorder->end(); + + return $ok; + } + + function runTests( $tests ) { + $ok = true; + + foreach ( $tests as $t ) { + $result = + $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] ); + $ok = $ok && $result; + $this->recorder->record( $t['test'], $result ); + } + + if ( $this->showProgress ) { + print "\n"; + } + + return $ok; + } + + /** + * Get a Parser object + * + * @param string $preprocessor + * @return Parser + */ + function getParser( $preprocessor = null ) { + global $wgParserConf; + + $class = $wgParserConf['class']; + $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf ); + + foreach ( $this->hooks as $tag => $callback ) { + $parser->setHook( $tag, $callback ); + } + + foreach ( $this->functionHooks as $tag => $bits ) { + list( $callback, $flags ) = $bits; + $parser->setFunctionHook( $tag, $callback, $flags ); + } + + wfRunHooks( 'ParserTestParser', array( &$parser ) ); + + return $parser; + } + + /** + * Run a given wikitext input through a freshly-constructed wiki parser, + * and compare the output against the expected results. + * Prints status and explanatory messages to stdout. + * + * @param $desc String: test's description + * @param $input String: wikitext to try rendering + * @param $result String: result to output + * @param $opts Array: test's options + * @param $config String: overrides for global variables, one per line + * @return Boolean + */ + public function runTest( $desc, $input, $result, $opts, $config ) { + if ( $this->showProgress ) { + $this->showTesting( $desc ); + } + + $opts = $this->parseOptions( $opts ); + $context = $this->setupGlobals( $opts, $config ); + + $user = $context->getUser(); + $options = ParserOptions::newFromContext( $context ); + + if ( isset( $opts['title'] ) ) { + $titleText = $opts['title']; + } else { + $titleText = 'Parser test'; + } + + $local = isset( $opts['local'] ); + $preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null; + $parser = $this->getParser( $preprocessor ); + $title = Title::newFromText( $titleText ); + + if ( isset( $opts['pst'] ) ) { + $out = $parser->preSaveTransform( $input, $title, $user, $options ); + } elseif ( isset( $opts['msg'] ) ) { + $out = $parser->transformMsg( $input, $options, $title ); + } elseif ( isset( $opts['section'] ) ) { + $section = $opts['section']; + $out = $parser->getSection( $input, $section ); + } elseif ( isset( $opts['replace'] ) ) { + $section = $opts['replace'][0]; + $replace = $opts['replace'][1]; + $out = $parser->replaceSection( $input, $section, $replace ); + } elseif ( isset( $opts['comment'] ) ) { + $out = Linker::formatComment( $input, $title, $local ); + } elseif ( isset( $opts['preload'] ) ) { + $out = $parser->getPreloadText( $input, $title, $options ); + } else { + $output = $parser->parse( $input, $title, $options, true, true, 1337 ); + $output->setTOCEnabled( !isset( $opts['notoc'] ) ); + $out = $output->getText(); + + if ( isset( $opts['showtitle'] ) ) { + if ( $output->getTitleText() ) { + $title = $output->getTitleText(); + } + + $out = "$title\n$out"; + } + + if ( isset( $opts['ill'] ) ) { + $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) ); + } elseif ( isset( $opts['cat'] ) ) { + $outputPage = $context->getOutput(); + $outputPage->addCategoryLinks( $output->getCategories() ); + $cats = $outputPage->getCategoryLinks(); + + if ( isset( $cats['normal'] ) ) { + $out = $this->tidy( implode( ' ', $cats['normal'] ) ); + } else { + $out = ''; + } + } + + $result = $this->tidy( $result ); + } + + $this->teardownGlobals(); + + $testResult = new ParserTestResult( $desc ); + $testResult->expected = $result; + $testResult->actual = $out; + + return $this->showTestResult( $testResult ); + } + + /** + * Refactored in 1.22 to use ParserTestResult + */ + function showTestResult( ParserTestResult $testResult ) { + if ( $testResult->isSuccess() ) { + $this->showSuccess( $testResult ); + return true; + } else { + $this->showFailure( $testResult ); + return false; + } + } + + /** + * Use a regex to find out the value of an option + * @param $key String: name of option val to retrieve + * @param $opts array: Options array to look in + * @param $default Mixed: default value returned if not found + */ + private static function getOptionValue( $key, $opts, $default ) { + $key = strtolower( $key ); + + if ( isset( $opts[$key] ) ) { + return $opts[$key]; + } else { + return $default; + } + } + + private function parseOptions( $instring ) { + $opts = array(); + // foo + // foo=bar + // foo="bar baz" + // foo=[[bar baz]] + // foo=bar,"baz quux" + $regex = '/\b + ([\w-]+) # Key + \b + (?:\s* + = # First sub-value + \s* + ( + " + [^"]* # Quoted val + " + | + \[\[ + [^]]* # Link target + \]\] + | + [\w-]+ # Plain word + ) + (?:\s* + , # Sub-vals 1..N + \s* + ( + "[^"]*" # Quoted val + | + \[\[[^]]*\]\] # Link target + | + [\w-]+ # Plain word + ) + )* + )? + /x'; + + if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) { + foreach ( $matches as $bits ) { + array_shift( $bits ); + $key = strtolower( array_shift( $bits ) ); + if ( count( $bits ) == 0 ) { + $opts[$key] = true; + } elseif ( count( $bits ) == 1 ) { + $opts[$key] = $this->cleanupOption( array_shift( $bits ) ); + } else { + // Array! + $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits ); + } + } + } + return $opts; + } + + private function cleanupOption( $opt ) { + if ( substr( $opt, 0, 1 ) == '"' ) { + return substr( $opt, 1, -1 ); + } + + if ( substr( $opt, 0, 2 ) == '[[' ) { + return substr( $opt, 2, -2 ); + } + return $opt; + } + + /** + * Set up the global variables for a consistent environment for each test. + * Ideally this should replace the global configuration entirely. + */ + private function setupGlobals( $opts = '', $config = '' ) { + # Find out values for some special options. + $lang = + self::getOptionValue( 'language', $opts, 'en' ); + $variant = + self::getOptionValue( 'variant', $opts, false ); + $maxtoclevel = + self::getOptionValue( 'wgMaxTocLevel', $opts, 999 ); + $linkHolderBatchSize = + self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 ); + + $settings = array( + 'wgServer' => 'http://example.org', + 'wgScript' => '/index.php', + 'wgScriptPath' => '/', + 'wgArticlePath' => '/wiki/$1', + 'wgActionPaths' => array(), + 'wgLockManagers' => array( array( + 'name' => 'fsLockManager', + 'class' => 'FSLockManager', + 'lockDirectory' => $this->uploadDir . '/lockdir', + ), array( + 'name' => 'nullLockManager', + 'class' => 'NullLockManager', + ) ), + 'wgLocalFileRepo' => array( + 'class' => 'LocalRepo', + 'name' => 'local', + 'url' => 'http://example.com/images', + 'hashLevels' => 2, + 'transformVia404' => false, + 'backend' => new FSFileBackend( array( + 'name' => 'local-backend', + 'lockManager' => 'fsLockManager', + 'containerPaths' => array( + 'local-public' => $this->uploadDir, + 'local-thumb' => $this->uploadDir . '/thumb', + 'local-temp' => $this->uploadDir . '/temp', + 'local-deleted' => $this->uploadDir . '/delete', + ) + ) ) + ), + 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ), + 'wgStylePath' => '/skins', + 'wgSitename' => 'MediaWiki', + 'wgLanguageCode' => $lang, + 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'parsertest_' : 'pt_', + 'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ), + 'wgLang' => null, + 'wgContLang' => null, + 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ), + 'wgMaxTocLevel' => $maxtoclevel, + 'wgCapitalLinks' => true, + 'wgNoFollowLinks' => true, + 'wgNoFollowDomainExceptions' => array(), + 'wgThumbnailScriptPath' => false, + 'wgUseImageResize' => true, + 'wgSVGConverter' => 'null', + 'wgSVGConverters' => array( 'null' => 'echo "1">$output' ), + 'wgLocaltimezone' => 'UTC', + 'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ), + 'wgUseTidy' => false, + 'wgDefaultLanguageVariant' => $variant, + 'wgVariantArticlePath' => false, + 'wgGroupPermissions' => array( '*' => array( + 'createaccount' => true, + 'read' => true, + 'edit' => true, + 'createpage' => true, + 'createtalk' => true, + ) ), + 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ), + 'wgDefaultExternalStore' => array(), + 'wgForeignFileRepos' => array(), + 'wgLinkHolderBatchSize' => $linkHolderBatchSize, + 'wgExperimentalHtmlIds' => false, + 'wgExternalLinkTarget' => false, + 'wgAlwaysUseTidy' => false, + 'wgHtml5' => true, + 'wgWellFormedXml' => true, + 'wgAllowMicrodataAttributes' => true, + 'wgAdaptiveMessageCache' => true, + 'wgDisableLangConversion' => false, + 'wgDisableTitleConversion' => false, + ); + + if ( $config ) { + $configLines = explode( "\n", $config ); + + foreach ( $configLines as $line ) { + list( $var, $value ) = explode( '=', $line, 2 ); + + $settings[$var] = eval( "return $value;" ); + } + } + + $this->savedGlobals = array(); + + /** @since 1.20 */ + wfRunHooks( 'ParserTestGlobals', array( &$settings ) ); + + foreach ( $settings as $var => $val ) { + if ( array_key_exists( $var, $GLOBALS ) ) { + $this->savedGlobals[$var] = $GLOBALS[$var]; + } + + $GLOBALS[$var] = $val; + } + + $GLOBALS['wgContLang'] = Language::factory( $lang ); + $GLOBALS['wgMemc'] = new EmptyBagOStuff; + + $context = new RequestContext(); + $GLOBALS['wgLang'] = $context->getLanguage(); + $GLOBALS['wgOut'] = $context->getOutput(); + + $GLOBALS['wgUser'] = new User(); + + global $wgHooks; + + $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup'; + $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp'; + + MagicWord::clearCache(); + + return $context; + } + + /** + * List of temporary tables to create, without prefix. + * Some of these probably aren't necessary. + */ + private function listTables() { + $tables = array( 'user', 'user_properties', 'user_former_groups', 'page', 'page_restrictions', + 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks', + 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks', + 'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage', + 'recentchanges', 'watchlist', 'interwiki', 'logging', + 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo', + 'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links' + ); + + if ( in_array( $this->db->getType(), array( 'mysql', 'sqlite', 'oracle' ) ) ) { + array_push( $tables, 'searchindex' ); + } + + // Allow extensions to add to the list of tables to duplicate; + // may be necessary if they hook into page save or other code + // which will require them while running tests. + wfRunHooks( 'ParserTestTables', array( &$tables ) ); + + return $tables; + } + + /** + * Set up a temporary set of wiki tables to work with for the tests. + * Currently this will only be done once per run, and any changes to + * the db will be visible to later tests in the run. + */ + public function setupDatabase() { + global $wgDBprefix; + + if ( $this->databaseSetupDone ) { + return; + } + + $this->db = wfGetDB( DB_MASTER ); + $dbType = $this->db->getType(); + + if ( $wgDBprefix === 'parsertest_' || ( $dbType == 'oracle' && $wgDBprefix === 'pt_' ) ) { + throw new MWException( 'setupDatabase should be called before setupGlobals' ); + } + + $this->databaseSetupDone = true; + $this->oldTablePrefix = $wgDBprefix; + + # SqlBagOStuff broke when using temporary tables on r40209 (bug 15892). + # It seems to have been fixed since (r55079?), but regressed at some point before r85701. + # This works around it for now... + ObjectCache::$instances[CACHE_DB] = new HashBagOStuff; + + # CREATE TEMPORARY TABLE breaks if there is more than one server + if ( wfGetLB()->getServerCount() != 1 ) { + $this->useTemporaryTables = false; + } + + $temporary = $this->useTemporaryTables || $dbType == 'postgres'; + $prefix = $dbType != 'oracle' ? 'parsertest_' : 'pt_'; + + $this->dbClone = new CloneDatabase( $this->db, $this->listTables(), $prefix ); + $this->dbClone->useTemporaryTables( $temporary ); + $this->dbClone->cloneTableStructure(); + + if ( $dbType == 'oracle' ) { + $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' ); + # Insert 0 user to prevent FK violations + + # Anonymous user + $this->db->insert( 'user', array( + 'user_id' => 0, + 'user_name' => 'Anonymous' ) ); + } + + # Update certain things in site_stats + $this->db->insert( 'site_stats', + array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ) ); + + # Reinitialise the LocalisationCache to match the database state + Language::getLocalisationCache()->unloadAll(); + + # Clear the message cache + MessageCache::singleton()->clear(); + + // 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' => 7881, + 'width' => 1941, + 'height' => 220, + 'bits' => 8, + 'media_type' => MEDIATYPE_BITMAP, + 'mime' => 'image/jpeg', + 'metadata' => serialize( array() ), + '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]] + $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) ); + $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', array( + 'size' => 12345, + 'width' => 320, + 'height' => 240, + 'bits' => 24, + 'media_type' => MEDIATYPE_BITMAP, + 'mime' => 'image/jpeg', + 'metadata' => serialize( array() ), + 'sha1' => wfBaseConvert( '3', 16, 36, 31 ), + 'fileExists' => true + ), $this->db->timestamp( '20010115123500' ), $user ); + } + + public function teardownDatabase() { + if ( !$this->databaseSetupDone ) { + $this->teardownGlobals(); + return; + } + $this->teardownUploadDir( $this->uploadDir ); + + $this->dbClone->destroy(); + $this->databaseSetupDone = false; + + if ( $this->useTemporaryTables ) { + if ( $this->db->getType() == 'sqlite' ) { + # Under SQLite the searchindex table is virtual and need + # to be explicitly destroyed. See bug 29912 + # See also MediaWikiTestCase::destroyDB() + wfDebug( __METHOD__ . " explicitly destroying sqlite virtual table parsertest_searchindex\n" ); + $this->db->query( "DROP TABLE `parsertest_searchindex`" ); + } + # Don't need to do anything + $this->teardownGlobals(); + return; + } + + $tables = $this->listTables(); + + foreach ( $tables as $table ) { + 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' ) { + $this->db->query( 'BEGIN FILL_WIKI_INFO; END;' ); + } + + $this->teardownGlobals(); + } + + /** + * Create a dummy uploads directory which will contain a couple + * of files in order to pass existence tests. + * + * @return String: the directory + */ + private function setupUploadDir() { + global $IP; + + if ( $this->keepUploads ) { + $dir = wfTempDir() . '/mwParser-images'; + + if ( is_dir( $dir ) ) { + return $dir; + } + } else { + $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; + } + + // wfDebug( "Creating upload directory $dir\n" ); + if ( file_exists( $dir ) ) { + wfDebug( "Already exists!\n" ); + return $dir; + } + + wfMkdirParents( $dir . '/3/3a', null, __METHOD__ ); + copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); + wfMkdirParents( $dir . '/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; + } + + /** + * Restore default values and perform any necessary clean-up + * after each test runs. + */ + private function teardownGlobals() { + RepoGroup::destroySingleton(); + FileBackendGroup::destroySingleton(); + LockManagerGroup::destroySingletons(); + LinkCache::singleton()->clear(); + + foreach ( $this->savedGlobals as $var => $val ) { + $GLOBALS[$var] = $val; + } + } + + /** + * Remove the dummy uploads directory + */ + private function teardownUploadDir( $dir ) { + if ( $this->keepUploads ) { + return; + } + + // delete the files first, then the dirs. + self::deleteFiles( + array( + "$dir/3/3a/Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/30px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/40px-Foobar.jpg", + "$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", + ) + ); + + self::deleteDirs( + array( + "$dir/3/3a", + "$dir/3", + "$dir/thumb/6/65", + "$dir/thumb/6", + "$dir/thumb/3/3a/Foobar.jpg", + "$dir/thumb/3/3a", + "$dir/thumb/3", + "$dir/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", + "$dir/math/f/a/5", + "$dir/math/f/a", + "$dir/math/f", + "$dir/math", + "$dir", + ) + ); + } + + /** + * Delete the specified files, if they exist. + * @param $files Array: full paths to files to delete. + */ + private static function deleteFiles( $files ) { + foreach ( $files as $file ) { + if ( file_exists( $file ) ) { + unlink( $file ); + } + } + } + + /** + * Delete the specified directories, if they exist. Must be empty. + * @param $dirs Array: full paths to directories to delete. + */ + private static function deleteDirs( $dirs ) { + foreach ( $dirs as $dir ) { + if ( is_dir( $dir ) ) { + rmdir( $dir ); + } + } + } + + /** + * "Running test $desc..." + */ + protected function showTesting( $desc ) { + print "Running test $desc... "; + } + + /** + * Print a happy success message. + * + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult + * @return Boolean + */ + protected function showSuccess( ParserTestResult $testResult ) { + if ( $this->showProgress ) { + print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n"; + } + + return true; + } + + /** + * Print a failure message and provide some explanatory output + * about what went wrong if so configured. + * + * Refactored in 1.22 to use ParserTestResult + * + * @param $testResult ParserTestResult + * @return Boolean + */ + 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( $testResult->description ); + } + + print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n"; + + if ( $this->showOutput ) { + print "--- Expected ---\n{$testResult->expected}\n"; + print "--- Actual ---\n{$testResult->actual}\n"; + } + + if ( $this->showDiffs ) { + print $this->quickDiff( $testResult->expected, $testResult->actual ); + if ( !$this->wellFormed( $testResult->actual ) ) { + print "XML error: $this->mXmlError\n"; + } + } + } + + return false; + } + + /** + * Run given strings through a diff and return the (colorized) output. + * Requires writable /tmp directory and a 'diff' command in the PATH. + * + * @param $input String + * @param $output String + * @param $inFileTail String: tailing for the input file name + * @param $outFileTail String: tailing for the output file name + * @return String + */ + protected function quickDiff( $input, $output, + $inFileTail = 'expected', $outFileTail = 'actual' + ) { + # Windows, or at least the fc utility, is retarded + $slash = wfIsWindows() ? '\\' : '/'; + $prefix = wfTempDir() . "{$slash}mwParser-" . mt_rand(); + + $infile = "$prefix-$inFileTail"; + $this->dumpToFile( $input, $infile ); + + $outfile = "$prefix-$outFileTail"; + $this->dumpToFile( $output, $outfile ); + + $shellInfile = wfEscapeShellArg( $infile ); + $shellOutfile = wfEscapeShellArg( $outfile ); + + global $wgDiff3; + // we assume that people with diff3 also have usual diff + $shellCommand = ( wfIsWindows() && !$wgDiff3 ) ? 'fc' : 'diff -au'; + + $diff = wfShellExec( "$shellCommand $shellInfile $shellOutfile" ); + + unlink( $infile ); + unlink( $outfile ); + + return $this->colorDiff( $diff ); + } + + /** + * Write the given string to a file, adding a final newline. + * + * @param $data String + * @param $filename String + */ + private function dumpToFile( $data, $filename ) { + $file = fopen( $filename, "wt" ); + fwrite( $file, $data . "\n" ); + fclose( $file ); + } + + /** + * Colorize unified diff output if set for ANSI color output. + * Subtractions are colored blue, additions red. + * + * @param $text String + * @return String + */ + protected function colorDiff( $text ) { + return preg_replace( + array( '/^(-.*)$/m', '/^(\+.*)$/m' ), + array( $this->term->color( 34 ) . '$1' . $this->term->reset(), + $this->term->color( 31 ) . '$1' . $this->term->reset() ), + $text ); + } + + /** + * Show "Reading tests from ..." + * + * @param $path String + */ + public function showRunFile( $path ) { + print $this->term->color( 1 ) . + "Reading tests from \"$path\"..." . + $this->term->reset() . + "\n"; + } + + /** + * Insert a temporary test article + * @param $name String: the title, including any prefix + * @param $text String: the article text + * @param $line Integer: the input line number, for reporting errors + * @param $ignoreDuplicate Boolean: whether to silently ignore duplicate pages + */ + public static function addArticle( $name, $text, $line = 'unknown', $ignoreDuplicate = '' ) { + global $wgCapitalLinks; + + $oldCapitalLinks = $wgCapitalLinks; + $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637 + + $text = self::chomp( $text ); + $name = self::chomp( $name ); + + $title = Title::newFromText( $name ); + + if ( is_null( $title ) ) { + throw new MWException( "invalid title '$name' at line $line\n" ); + } + + $page = WikiPage::factory( $title ); + $page->loadPageData( 'fromdbmaster' ); + + if ( $page->exists() ) { + if ( $ignoreDuplicate == 'ignoreduplicate' ) { + return; + } else { + throw new MWException( "duplicate article '$name' at line $line\n" ); + } + } + + $page->doEditContent( ContentHandler::makeContent( $text, $title ), '', EDIT_NEW ); + + $wgCapitalLinks = $oldCapitalLinks; + } + + /** + * Steal a callback function from the primary parser, save it for + * application to our scary parser. If the hook is not installed, + * abort processing of this file. + * + * @param $name String + * @return Bool true if tag hook is present + */ + public function requireHook( $name ) { + global $wgParser; + + $wgParser->firstCallInit(); // make sure hooks are loaded. + + if ( isset( $wgParser->mTagHooks[$name] ) ) { + $this->hooks[$name] = $wgParser->mTagHooks[$name]; + } else { + echo " This test suite requires the '$name' hook extension, skipping.\n"; + return false; + } + + return true; + } + + /** + * Steal a callback function from the primary parser, save it for + * application to our scary parser. If the hook is not installed, + * abort processing of this file. + * + * @param $name String + * @return Bool true if function hook is present + */ + public function requireFunctionHook( $name ) { + global $wgParser; + + $wgParser->firstCallInit(); // make sure hooks are loaded. + + if ( isset( $wgParser->mFunctionHooks[$name] ) ) { + $this->functionHooks[$name] = $wgParser->mFunctionHooks[$name]; + } else { + echo " This test suite requires the '$name' function hook extension, skipping.\n"; + return false; + } + + return true; + } + + /** + * Run the "tidy" command on text if the $wgUseTidy + * global is true + * + * @param $text String: the text to tidy + * @return String + */ + private function tidy( $text ) { + global $wgUseTidy; + + if ( $wgUseTidy ) { + $text = MWTidy::tidy( $text ); + } + + return $text; + } + + private function wellFormed( $text ) { + $html = + Sanitizer::hackDocType() . + '<html>' . + $text . + '</html>'; + + $parser = xml_parser_create( "UTF-8" ); + + # case folding violates XML standard, turn it off + xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); + + if ( !xml_parse( $parser, $html, true ) ) { + $err = xml_error_string( xml_get_error_code( $parser ) ); + $position = xml_get_current_byte_index( $parser ); + $fragment = $this->extractFragment( $html, $position ); + $this->mXmlError = "$err at byte $position:\n$fragment"; + xml_parser_free( $parser ); + + return false; + } + + xml_parser_free( $parser ); + + return true; + } + + private function extractFragment( $text, $position ) { + $start = max( 0, $position - 10 ); + $before = $position - $start; + $fragment = '...' . + $this->term->color( 34 ) . + substr( $text, $start, $before ) . + $this->term->color( 0 ) . + $this->term->color( 31 ) . + $this->term->color( 1 ) . + substr( $text, $position, 1 ) . + $this->term->color( 0 ) . + $this->term->color( 34 ) . + substr( $text, $position + 1, 9 ) . + $this->term->color( 0 ) . + '...'; + $display = str_replace( "\n", ' ', $fragment ); + $caret = ' ' . + str_repeat( ' ', $before ) . + $this->term->color( 31 ) . + '^' . + $this->term->color( 0 ); + + return "$display\n$caret"; + } + + static function getFakeTimestamp( &$parser, &$ts ) { + $ts = 123; //parsed as '1970-01-01T00:02:03Z' + return true; + } +} diff --git a/tests/parser/parserTests.txt b/tests/parser/parserTests.txt new file mode 100644 index 00000000..9658e8f8 --- /dev/null +++ b/tests/parser/parserTests.txt @@ -0,0 +1,18591 @@ +# MediaWiki Parser test cases +# Some taken from http://meta.wikimedia.org/wiki/Parser_testing +# All (C) their respective authors and released under the GPL +# +# The syntax should be fairly self-explanatory. +# +# Currently supported test options: +# One of the following three: +# +# (default) generate HTML output +# pst apply pre-save transform +# msg apply message transform +# +# Plus any combination of these: +# +# cat add category links +# ill add inter-language links +# subpage enable subpages (disabled by default) +# noxml don't check for XML well formdness +# title=[[XXX]] run test using article title XXX +# language=XXX set content language to XXX for this test +# variant=XXX set the variant of language for this test (eg zh-tw) +# disabled do not run test +# parsoid parsoid-only test (not run by PHP parser) +# php php-only test (not run by the parsoid parser) +# 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 +# where '/' denotes a newline. + +# This is the standard article assumed to exist. +!! article +Main Page +!! text +blah blah +!! endarticle + +!!article +Template:Foo +!!text +FOO +!!endarticle + +!! article +Template:Blank +!! text +!! endarticle + +!! article +Template:pipe +!! text +| +!! endarticle + +!!article +MediaWiki:bad image list +!!text +* [[File:Bad.jpg]] except [[Nasty page]] +!!endarticle + +!! article +Template:inner list +!! text +* item 1 +!! endarticle + +!! article +Template:tbl-start +!! text +{| +!! endarticle + +!! article +Template:tbl-end +!! text +|} +!! endarticle + +!! article +Template:! +!! text +| +!! endarticle + +!! article +Template:echo +!! text +{{{1}}} +!! endarticle + +!! article +Template:echo_with_span +!! text +<span>{{{1}}}</span> +!! endarticle + +!! article +Template:echo_with_div +!! text +<div>{{{1}}}</div> +!! endarticle + +!! article +Template:attr_str +!! text +{{{1}}}="{{{2}}}" +!! endarticle + +!! article +Template:table_attribs +!! text +<noinclude> +|</noinclude>style="color: red"| Foo +!! 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 +### +!! test +Blank input +!! input +!! result +!! end + + +!! test +Simple paragraph +!! input +This is a simple paragraph. +!! result +<p>This is a simple paragraph. +</p> +!! end + +!! test +Paragraphs with extra newline spacing +!! input +foo + +bar + + +baz + + + +booz +!! result +<p>foo +</p><p>bar +</p><p><br /> +baz +</p><p><br /> +</p><p>booz +</p> +!! 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/🍺 +<!-- EasterEgg we love beer, better be able be able to link to it --> +!! result +<p><a rel="nofollow" class="external free" href="http://fr.wikipedia.org/wiki/🍺">http://fr.wikipedia.org/wiki/🍺</a> +</p> +!! end + +!! test +Simple list +!! input +* Item 1 +* Item 2 +!! result +<ul> +<li> Item 1 +</li> +<li> Item 2 +</li> +</ul> + +!! end + +!! test +Italics and bold +!! input +* plain +* plain''italic''plain +* plain''italic''plain''italic''plain +* plain'''bold'''plain +* plain'''bold'''plain'''bold'''plain +* plain''italic''plain'''bold'''plain +* plain'''bold'''plain''italic''plain +* plain''italic'''bold-italic'''italic''plain +* plain'''bold''bold-italic''bold'''plain +* plain'''''bold-italic'''italic''plain +* plain'''''bold-italic''bold'''plain +* plain''italic'''bold-italic'''''plain +* plain'''bold''bold-italic'''''plain +* plain l'''italic''plain +* plain l''''bold''' plain +!! result +<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 +### +!! test +Italics and bold: 2-quote opening sequence: (2,2) +!! input +''foo'' +!! result +<p><i>foo</i> +</p> +!!end + + +!! test +Italics and bold: 2-quote opening sequence: (2,3) +!! input +''foo''' +!! result +<p><i>foo'</i> +</p> +!!end + + +!! test +Italics and bold: 2-quote opening sequence: (2,4) +!! input +''foo'''' +!! result +<p><i>foo''</i> +</p> +!!end + + +!! test +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 + + +### +### 3-quote opening sequence tests +### + +!! test +Italics and bold: 3-quote opening sequence: (3,2) +!! input +'''foo'' +!! result +<p>'<i>foo</i> +</p> +!!end + + +!! test +Italics and bold: 3-quote opening sequence: (3,3) +!! input +'''foo''' +!! result +<p><b>foo</b> +</p> +!!end + + +!! test +Italics and bold: 3-quote opening sequence: (3,4) +!! input +'''foo'''' +!! result +<p><b>foo'</b> +</p> +!!end + + +!! test +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 + + +### +### 4-quote opening sequence tests +### + +!! test +Italics and bold: 4-quote opening sequence: (4,2) +!! input +''''foo'' +!! result +<p>''<i>foo</i> +</p> +!!end + + +!! test +Italics and bold: 4-quote opening sequence: (4,3) +!! input +''''foo''' +!! result +<p>'<b>foo</b> +</p> +!!end + + +!! test +Italics and bold: 4-quote opening sequence: (4,4) +!! input +''''foo'''' +!! result +<p>'<b>foo'</b> +</p> +!!end + + +!! test +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 + + +### +### 5-quote opening sequence tests +### + +!! test +Italics and bold: 5-quote opening sequence: (5,2) +!! options +!! input +'''''foo'' +!! result +<p><b><i>foo</i></b> +</p> +!!end + + +!! test +Italics and bold: 5-quote opening sequence: (5,3) +!! input +'''''foo''' +!! result +<p><i><b>foo</b></i> +</p> +!!end + + +!! test +Italics and bold: 5-quote opening sequence: (5,4) +!! input +'''''foo'''' +!! result +<p><i><b>foo'</b></i> +</p> +!!end + + +!! test +Italics and bold: 5-quote opening sequence: (5,5) +!! input +'''''foo''''' +!! result +<p><i><b>foo</b></i> +</p> +!!end + +### +### multiple quote sequences in a line +### +!! test +Italics and bold: multiple quote sequences: (2,4,2) +!! input +''foo''''bar'' +!! result +<p><i>foo'<b>bar</b></i> +</p> +!!end + + +!! test +Italics and bold: multiple quote sequences: (2,4,3) +!! input +''foo''''bar''' +!! result +<p><i>foo'<b>bar</b></i> +</p> +!!end + + +!! test +Italics and bold: multiple quote sequences: (2,4,4) +!! input +''foo''''bar'''' +!! result +<p><i>foo'<b>bar'</b></i> +</p> +!!end + + +!! test +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) (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 +### +!! test +Italics and bold: other quote tests: (2,3,5) +!! input +''this is about '''foo's family''''' +!! result +<p><i>this is about <b>foo's family</b></i> +</p> +!!end + + +!! test +Italics and bold: other quote tests: (2,(3,3),2) +!! input +''this is about '''foo's''' family'' +!! result +<p><i>this is about <b>foo's</b> family</i> +</p> +!!end + + +!! test +Italics and bold: other quote tests: (3,2,3,2) +!! input +'''this is about ''foo'''s family'' +!! result +<p><b>this is about <i>foo</i></b><i>s family</i> +</p> +!!end + + +!! test +Italics and bold: other quote tests: (3,2,3,3) +!! options +!! input +'''this is about ''foo'''s family''' +!! result +<p>'<i>this is about </i>foo<b>s family</b> +</p> +!!end + + +!! test +Italics and bold: other quote tests: (3,(2,2),3) +!! input +'''this is about ''foo's'' family''' +!! result +<p><b>this is about <i>foo's</i> family</b> +</p> +!!end + + +!! test +Italicized possessive +!! input +The ''[[Main Page]]'''s talk page. +!! result +<p>The <i><a href="/wiki/Main_Page" title="Main Page">Main Page</a>'</i>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 +### + +!! test +Non-html5 tags should be accepted +!! input +<center>''foo''</center> +<big>''foo''</big> +<font>''foo''</font> +<strike>''foo''</strike> +<tt>''foo''</tt> +!! result +<center><i>foo</i></center> +<p><big><i>foo</i></big> +<font><i>foo</i></font> +<strike><i>foo</i></strike> +<tt><i>foo</i></tt> +</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 +### + +!! test +<nowiki> unordered list +!! input +<nowiki>* This is not an unordered list item.</nowiki> +!! result +<p>* This is not an unordered list item. +</p> +!! end + +!! test +<nowiki> spacing +!! input +<nowiki>Lorem ipsum dolor + +sed abit. + sed nullum. + +:and a colon +</nowiki> +!! result +<p>Lorem ipsum dolor + +sed abit. + sed nullum. + +:and a colon + +</p> +!! end + +!! test +nowiki 3 +!! input +:There is not nowiki. +:There is <nowiki>nowiki</nowiki>. + +#There is not nowiki. +#There is <nowiki>nowiki</nowiki>. + +*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> + +!! end + +!! test +Entities inside <nowiki> +!! input +<nowiki><</nowiki> +!! result +<p>< +</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 +### +!! test +Comments and Indent-Pre +!! input +<!-- comment 1 --> asdf + +<!-- comment 1 --> asdf +<!-- comment 2 --> + +<!-- comment 1 --> asdf +<!-- comment 2 -->xyz + +<!-- comment 1 --> asdf +<!-- comment 2 --> xyz +!! result +<pre>asdf +</pre> +<pre>asdf +</pre> +<pre>asdf +</pre> +<p>xyz +</p> +<pre>asdf +xyz +</pre> +!! end + +!! test +Comment test 2a +!! input +asdf +<!-- comment 1 --> +jkl +!! result +<p>asdf +jkl +</p> +!! end + +!! test +Comment test 2b +!! input +asdf +<!-- comment 1 --> + +jkl +!! result +<p>asdf +</p><p>jkl +</p> +!! end + +!! test +Comment test 3 +!! input +asdf +<!-- comment 1 --> +<!-- comment 2 --> +jkl +!! result +<p>asdf +jkl +</p> +!! end + +!! test +Comment test 4 +!! input +asdf<!-- comment 1 -->jkl +!! result +<p>asdfjkl +</p> +!! end + +!! test +Comment spacing +!! input +a + <!-- foo --> b <!-- bar --> +c +!! result +<p>a +</p> +<pre> b +</pre> +<p>c +</p> +!! end + +!! test +Comment whitespace +!! input +<!-- returns a single newline, not nothing, since the newline after > is not stripped --> +!! result + +!! end + +!! test +Comment semantics and delimiters +!! input +<!-- --><!----><!-----><!------> +!! result + +!! end + +!! test +Comment semantics and delimiters, redux +!! input +<!-- In SGML every "foo" here would actually show up in the text -- foo -- bar +-- foo -- funky huh? ... --> +!! result + +!! end + +!! test +Comment semantics and delimiters: directors cut +!! input +<!-- ... However we like to keep things simple and somewhat XML-ish so we eat +everything starting with < followed by !-- until the first -- and > we see, +that wouldn't be valid XML however, since in XML -- has to terminate a comment +-->--> +!! result +<p>--> +</p> +!! end + +!! test +Comment semantics: nesting +!! input +<!--<!-- no, we're not going to do anything fancy here -->--> +!! result +<p>--> +</p> +!! end + +!! test +Comment semantics: unclosed comment at end +!! input +<!--This comment will run out to the end of the document +!! result + +!! end + +!! test +Comment in template title +!! input +{{f<!---->oo}} +!! result +<p>FOO +</p> +!! end + +!! test +Comment on its own line post-expand +!! input +a +{{blank}}<!----> +b +!! result +<p>a +</p><p>b +</p> +!! end + +!! test +Comment on its own line post-expand with non-significant whitespace +!! input +a + {{blank}} <!----> +b +!! result +<p>a +</p><p>b +</p> +!! end + +### +### paragraph wrapping tests +### +!! test +No block tags +!! input +a + +b +!! result +<p>a +</p><p>b +</p> +!! end + +!! test +Block tag on one line (<div>) +!! input +a <div>foo</div> + +b +!! result +a <div>foo</div> +<p>b +</p> +!! end + +!! test +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> + +b <div>foo</div> +!! result +a <div>foo</div> +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 +b +c +d<!--foo--> e +x <div>foo</div> z +!! result +<div>foo</div> a +<p>b +c +d e +</p> +x <div>foo</div> z + +!! end + +!! test +Empty lines between lines with block tags +!! input +<div></div> + + +<div></div>a + +b +<div>a</div>b + +<div>b</div>d + + +<div>e</div> +!! result +<div></div> +<p><br /> +</p> +<div></div>a +<p>b +</p> +<div>a</div>b +<div>b</div>d +<p><br /> +</p> +<div>e</div> + +!! end + +### +### Preformatted text +### +!! test +Preformatted text +!! input + This is some + Preformatted text + With ''italic'' + And '''bold''' + And a [[Main Page|link]] +!! result +<pre>This is some +Preformatted text +With <i>italic</i> +And <b>bold</b> +And a <a href="/wiki/Main_Page" title="Main Page">link</a> +</pre> +!! 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 + ''b'' +!! result +<pre>a +<i>b</i> +</pre> +!! end + +!! test +<pre> with <nowiki> inside (compatibility with 1.6 and earlier) +!! input +<pre><nowiki> +<b> +<cite> +<em> +</nowiki></pre> +!! result +<pre> +<b> +<cite> +<em> +</pre> + +!! end + +!! test +Regression with preformatted in <center> +!! input +<center> + Blah +</center> +!! result +<center> +<pre>Blah +</pre> +</center> + +!! end + +!! test +Bug 52763: Preformatted in <blockquote> +!! input +<blockquote> + Blah +</blockquote> +!! result +<blockquote> +<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 + +!! test +<pre> with attributes (bug 3202) +!! input +<pre style="background: blue; color:white">Bluescreen of WikiDeath</pre> +!! result +<pre style="background: blue; color:white">Bluescreen of WikiDeath</pre> + +!! end + +!! test +<pre> with width attribute (bug 3202) +!! input +<pre width="8">Narrow screen goodies</pre> +!! result +<pre width="8">Narrow screen goodies</pre> + +!! end + +!! test +<pre> with forbidden attribute (bug 3202) +!! input +<pre width="8" onmouseover="alert(document.cookie)">Narrow screen goodies</pre> +!! result +<pre width="8">Narrow screen goodies</pre> + +!! end + +!! test +Entities inside <pre> +!! input +<pre><</pre> +!! result +<pre><</pre> + +!! end + +!! test +<pre> with forbidden attribute values (bug 3202) +!! input +<pre width="8" style="border-width: expression(alert(document.cookie))">Narrow screen goodies</pre> +!! result +<pre width="8" style="/* insecure input */">Narrow screen goodies</pre> + +!! end + +!! test +<nowiki> inside <pre> (bug 13238) +!! input +<pre> +<nowiki> +</pre> +<pre> +<nowiki></nowiki> +</pre> +<pre><nowiki><nowiki></nowiki>Foo<nowiki></nowiki></nowiki></pre> +!! result +<pre> +<nowiki> +</pre> +<pre> + +</pre> +<pre><nowiki>Foo</nowiki></pre> + +!! end + +!! test +<nowiki> and <pre> preference (first one wins) +!! input +<pre> +<nowiki> +</pre> +</nowiki> +</pre> + +<nowiki> +<pre> +<nowiki> +</pre> +</nowiki> +</pre> + +!! result +<pre> +<nowiki> +</pre> +<p></nowiki> +</pre> +</p><p> +<pre> +<nowiki> +</pre> + +</pre> +</p> +!! end + +!! test +</pre> inside nowiki +!! input +<nowiki></pre></nowiki> +!! result +<p></pre> +</p> +!! end + +!!test +Templates: Indent-Pre: 1a. Templates that break a line should suppress <pre> +!!input + {{echo|}} +!!result + +!!end + +!!test +Templates: Indent-Pre: 1b. Templates that break a line should suppress <pre> +!!input + {{echo| +foo}} +!!result +<p>foo +</p> +!!end + +!! test +Templates: Indent-Pre: 1c: Wrapping should be based on expanded content +!! input + {{echo|a +b}} +!!result +<pre>a +</pre> +<p>b +</p> +!!end + +!! test +Templates: Indent-Pre: 1d: Wrapping should be based on expanded content +!! input + {{echo|a +b +c + d +e +}} +!!result +<pre>a +</pre> +<p>b +c +</p> +<pre>d +</pre> +<p>e +</p> +!!end + +!!test +Templates: Indent-Pre: 1e. Wrapping should be based on expanded content +!!input +{{echo| foo}} + +{{echo| foo}}{{echo| bar}} + +{{echo| foo}} +{{echo| bar}} + +{{echo|<!--cmt--> foo}} + +<!--cmt-->{{echo| foo}} + +{{echo|{{echo| }}bar}} +!!result +<pre>foo +</pre> +<pre>foo bar +</pre> +<pre>foo +bar +</pre> +<pre>foo +</pre> +<pre>foo +</pre> +<pre>bar +</pre> +!!end + +!! test +Templates: Indent-Pre: 1f: Wrapping should be based on expanded content +!! input +{{echo| }}a + +{{echo| + }}a + +{{echo| + b}} + +{{echo|a + }}b + +{{echo|a +}} b +!!result +<pre>a +</pre> +<p><br /> +</p> +<pre>a +</pre> +<p><br /> +</p> +<pre>b +</pre> +<p>a +</p> +<pre>b +</pre> +<p>a +</p> +<pre>b +</pre> +!!end + +# TODO / maybe: fix wt2wt for this +!! test +Parsoid: Don't paragraph-wrap fosterable content +!! options +parsoid=wt2html +!! input +{| +<td></td> +<td></td> + + + +|} +!! 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 +<p>a +</p><p>b +</p><p>c +</p> +<ul> +<li> d +</li> +</ul> + +!! end + +!! test +Templates: Don't strip whitespace from positional-param values +!! input +{{echo|a }} + +{{echo|{{echo|b}} }} + +{{echo| c +}} + +{{echo| {{echo|d}} +}} + +{{echo| + e}} + +{{echo| +* f}} + +{{echo| + }}g +!! result +<p>a +</p><p>b +</p> +<pre>c +</pre> +<p><br /> +</p> +<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> +!! 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 + +### +### Parsoid-centric tests for testing RT edge cases for pre +### + +!!test +1a. Indent-Pre and Comments +!!input + a +<!--a--> +c +!!result +<pre>a +</pre> +<p>c +</p> +!!end + +!!test +1b. Indent-Pre and Comments +!!input + a + <!--a--> +c +!!result +<pre>a +</pre> +<p>c +</p> +!!end + +!!test +1c. Indent-Pre and Comments +!!input +<!--a--> a + + <!--a--> a +!!result +<pre> a +</pre> +<pre> a +</pre> +!!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 + {| + |- + !h1!!h2 + |foo||bar + |} +!!result +<table> + +<tr> +<th>h1</th> +<th>h2 +</th> +<td>foo</td> +<td>bar +</td></tr></table> + +!!end + +!!test +2b. Indent-Pre and tables +!!input + {| + |- +|foo +|} +!!result +<table> + +<tr> +<td>foo +</td></tr></table> + +!!end + +!!test +2c. Indent-Pre and tables (bug 42252) +!!input +{| + |+ foo + ! | bar +|} +!!result +<table> +<caption> foo +</caption> +<tr> +<th> bar +</th></tr></table> + +!!end + +!!test +3a. Indent-Pre and block tags (single-line html) +!!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 + +!!test +3b. Indent-Pre and block tags (pre-content on separate line) +!!input +<p> + foo +</p> + +<div> + foo +</div> + +<center> + foo +</center> + +<blockquote> + foo +</blockquote> + +<blockquote> +<pre> +foo +</pre> +</blockquote> + +<table><tr><td> + foo +</td></tr></table> + +<ul><li> + foo +</li></ul> + +!!result +<p> + foo +</p> +<div> +<pre>foo +</pre> +</div> +<center> +<pre>foo +</pre> +</center> +<blockquote> +<p> foo +</p> +</blockquote> +<blockquote> +<pre> +foo +</pre> +</blockquote> +<table><tr><td> +<pre>foo +</pre> +</td></tr></table> +<ul><li> + foo +</li></ul> + +!!end + +!!test +4. Multiple spaces at start-of-line +!!input + <p> foo </p> + foo + {| +|foo +|} +!!result + <p> foo </p> +<pre> foo +</pre> +<table> +<tr> +<td>foo +</td></tr></table> + +!!end + +!! test +5. White-space in indent-pre +NOTE: the white-space char on 2nd line is significant +!! input + a<br/> + + b +!! result +<pre>a<br /> + +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) +### + +!!test +HTML-pre: 1. embedded newlines +!!input +<pre>foo</pre> + +<pre> +foo +</pre> + +<pre> + +foo +</pre> + +<pre> + + +foo +</pre> +!!result +<pre>foo</pre> +<pre> +foo +</pre> +<pre> + +foo +</pre> +<pre> + + +foo +</pre> + +!!end + +!!test +HTML-pre: 2: indented text +!!input +<pre> + foo +</pre> +!!result +<pre> + foo +</pre> + +!!end + +!!test +HTML-pre: 3: other wikitext +!!input +<pre> +* foo +# bar += no-h = +'' no-italic '' +[[ NoLink ]] +</pre> +!!result +<pre> +* foo +# bar += no-h = +'' no-italic '' +[[ NoLink ]] +</pre> + +!!end + +### +### Definition lists +### +!! test +Simple definition +!! input +; name : Definition +!! result +<dl> +<dt> name </dt> +<dd> Definition +</dd> +</dl> + +!! end + +!! test +Definition list for indentation only +!! input +: Indented text +!! result +<dl> +<dd> Indented text +</dd> +</dl> + +!! end + +!! test +Definition list with no space +!! input +;name:Definition +!! result +<dl> +<dt>name</dt> +<dd>Definition +</dd> +</dl> + +!!end + +!! test +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> + +!! end + +!! test +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> + +!! end + +!! test +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> + +!! end + +# At Brion's and JeLuF's insistence... :) +!! test +Definition list with news link containing colon +!! input +; news:alt.wikipedia.rox: This isn't even a real newsgroup! +!! result +<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 + +!! test +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> + +!! end + +!! test +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> + +!! end + +!! test +Definition lists: colon in HTML attribute +!! input +;<b style="display: inline">bold</b> +!! result +<dl> +<dt><b style="display: inline">bold</b> +</dt> +</dl> + +!! end + +!! test +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> + +!! end + +!! test +Bug 11748: Literal closing tags +!! input +<dl> +<dt>test 1</dt> +<dd>test test test test test</dd> +<dt>test 2</dt> +<dd>test test test test test</dd> +</dl> +!! result +<dl> +<dt>test 1</dt> +<dd>test test test test test</dd> +<dt>test 2</dt> +<dd>test test test test test</dd> +</dl> + +!! end + +!! test +Definition and unordered list using wiki syntax nested in unordered list using html tags. +!! input +<ul><li> +; term : description +* unordered +</li></ul> +!! result +<ul><li> +<dl> +<dt> term </dt> +<dd> description +</dd> +</dl> +<ul> +<li> unordered +</li> +</ul> +</li></ul> + +!! end + +!! test + +Definition list with empty definition and following paragraph +!! input +; term: +Paragraph text +!! result +<dl> +<dt> term</dt> +<dd> +</dd> +</dl> +<p>Paragraph text +</p> +!! end + +!! test +Nested definition lists using html syntax +!! input +<dl><dd> +<dl> +<dd>Foo</dd> +</dl> +</dd></dl> +!! result +<dl><dd> +<dl> +<dd>Foo</dd> +</dl> +</dd></dl> + +!! end + +!! test +Definition Lists: No nesting: Multiple dd's +!! input +;x +:a +:b +!! result +<dl> +<dt>x +</dt> +<dd>a +</dd> +<dd>b +</dd> +</dl> + +!! end + +!! test +Definition Lists: Indentation: Regular +!! input +:i1 +::i2 +:::i3 +!! result +<dl> +<dd>i1 +<dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> + +!! end + +!! test +Definition Lists: Indentation: Missing 1st level +!! input +::i2 +:::i3 +!! result +<dl> +<dd><dl> +<dd>i2 +<dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> + +!! end + +!! test +Definition Lists: Indentation: Multi-level indent +!! input +:::i3 +!! result +<dl> +<dd><dl> +<dd><dl> +<dd>i3 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> + +!! end + +!! test +Definition Lists: Hacky use to indent tables +!! input +::{| +|foo +|bar +|} +this text +should be left alone +!! result +<dl><dd><dl><dd><table> +<tr> +<td>foo +</td> +<td>bar +</td></tr></table></dd></dl></dd></dl> +<p>this text +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 +## ";;;t3 :d1". So, PHP parser behavior is a little inconsistent wrt multiple +## ";"s. +## +## Ex: ";;t2 ::d2" is transformed into: +## +## <dl> +## <dt>t2 </dt> +## <dd> +## <dl> +## <dt></dt> +## <dd>d2</dd> +## </dl> +## </dd> +## </dl> +## +## But, Parsoid treats "; :" as a tight atomic unit and excess ":" as plain text +## So, the same wikitext above (;;t2 ::d2) is transformed into: +## +## <dl> +## <dt> +## <dl> +## <dt>t2 </dt> +## <dd>:d2</dd> +## </dl> +## </dt> +## </dl> +## +## All Parsoid only definition list tests have this difference. +## +## See also: https://bugzilla.wikimedia.org/show_bug.cgi?id=6569 +## and http://lists.wikimedia.org/pipermail/wikitext-l/2011-November/000483.html + +!! test +Table / list interaction: indented table with lists in table contents +!! input +:{| +|- +| a +* b +|- +| c +* d +|} +!! result +<dl><dd><table> + +<tr> +<td> a +<ul> +<li> b +</li> +</ul> +</td></tr> +<tr> +<td> c +<ul> +<li> d +</li> +</ul> +</td></tr></table></dd></dl> + +!! end + +!!test +Table / list interaction: lists nested in tables nested in indented lists +!!input +:{| +| +:a +:b +| +*c +*d +|} + +*e +*f +!!result +<dl><dd><table> +<tr> +<td> +<dl> +<dd>a +</dd> +<dd>b +</dd> +</dl> +</td> +<td> +<ul> +<li>c +</li> +<li>d +</li> +</ul> +</td></tr></table></dd></dl> +<ul> +<li>e +</li> +<li>f +</li> +</ul> + +!!end + +!! test +Definition Lists: Nesting: Multi-level (Parsoid only) +!! options +parsoid +!! input +;t1 :d1 +;;t2 ::d2 +;;;t3 :::d3 +!! result +<dl> + <dt>t1 </dt> + <dd>d1</dd> + <dt> + <dl> + <dt>t2 </dt> + <dd>:d2</dd> + <dt> + <dl> + <dt>t3 </dt> + <dd>::d3</dd> + </dl> + </dt> + </dl> + </dt> +</dl> + + +!! end + + +!! test +Definition Lists: Nesting: Test 2 (Parsoid only) +!! options +parsoid +!! input +;t1 +::d2 +!! result +<dl> + <dt>t1</dt> + <dd> + <dl> + <dd>d2</dd> + </dl> + </dd> +</dl> + +!! end + + +!! test +Definition Lists: Nesting: Test 3 (Parsoid only) +!! options +parsoid +!! input +:;t1 +::::d2 +!! result +<dl> + <dd> + <dl> + <dt>t1</dt> + <dd> + <dl> + <dd> + <dl> + <dd>d2</dd> + </dl> + </dd> + </dl> + </dd> + </dl> + </dd> +</dl> + +!! end + + +!! test +Definition Lists: Nesting: Test 4 +!! input +::;t3 +:::d3 +!! result +<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 (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> + +!! 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 +!! input +*: d1 +*: d2 +!! result +<ul> +<li><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</li> +</ul> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 3 +!! input +*::: d1 +*::: d2 +!! result +<ul> +<li><dl> +<dd><dl> +<dd><dl> +<dd> d1 +</dd> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</dd> +</dl> +</li> +</ul> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 4 +!! input +*;d1 :d2 +*;d3 :d4 +!! result +<ul> +<li><dl> +<dt>d1 </dt> +<dd>d2 +</dd> +<dt>d3 </dt> +<dd>d4 +</dd> +</dl> +</li> +</ul> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 5 +!! input +*:d1 +*:: d2 +!! result +<ul> +<li><dl> +<dd>d1 +<dl> +<dd> d2 +</dd> +</dl> +</dd> +</dl> +</li> +</ul> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 6 +!! input +#*: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> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 7 +!! input +:* d1 +:* d2 +!! result +<dl> +<dd><ul> +<li> d1 +</li> +<li> d2 +</li> +</ul> +</dd> +</dl> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 8 +!! input +:* d1 +::* d2 +!! result +<dl> +<dd><ul> +<li> d1 +</li> +</ul> +<dl> +<dd><ul> +<li> d2 +</li> +</ul> +</dd> +</dl> +</dd> +</dl> + +!! end + + +!! test +Definition Lists: Mixed Lists: Test 9 +!! input +*;foo :bar +!! result +<ul> +<li><dl> +<dt>foo </dt> +<dd>bar +</dd> +</dl> +</li> +</ul> + +!! end + + +!! test +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> + +!! 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 (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> + +!! 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 (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> + +!! 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 +### +!! test +External links: non-bracketed +!! input +Non-bracketed: http://example.com +!! result +<p>Non-bracketed: <a rel="nofollow" class="external free" href="http://example.com">http://example.com</a> +</p> +!! end + +!! test +External links: numbered +!! input +Numbered: [http://example.com] +Numbered: [http://example.net] +Numbered: [http://example.com] +!! result +<p>Numbered: <a rel="nofollow" class="external autonumber" href="http://example.com">[1]</a> +Numbered: <a rel="nofollow" class="external autonumber" href="http://example.net">[2]</a> +Numbered: <a rel="nofollow" class="external autonumber" href="http://example.com">[3]</a> +</p> +!!end + +!! test +External links: specified text +!! input +Specified text: [http://example.com link] +!! result +<p>Specified text: <a rel="nofollow" class="external text" href="http://example.com">link</a> +</p> +!!end + +!! test +External links: trail +!! input +Linktrails should not work for external links: [http://example.com link]s +!! result +<p>Linktrails should not work for external links: <a rel="nofollow" class="external text" href="http://example.com">link</a>s +</p> +!! end + +!! test +External links: dollar sign in URL +!! input +http://example.com/1$2345 +!! result +<p><a rel="nofollow" class="external free" href="http://example.com/1$2345">http://example.com/1$2345</a> +</p> +!! end + +!! test +External links: dollar sign in URL (named) +!! input +[http://example.com/1$2345] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://example.com/1$2345">[1]</a> +</p> +!!end + +!! test +External links: open square bracket forbidden in URL (bug 4377) +!! input +http://example.com/1[2345 +!! result +<p><a rel="nofollow" class="external free" href="http://example.com/1">http://example.com/1</a>[2345 +</p> +!! end + +!! test +External links: open square bracket forbidden in URL (named) (bug 4377) +!! input +[http://example.com/1[2345] +!! result +<p><a rel="nofollow" class="external text" href="http://example.com/1">[2345</a> +</p> +!!end + +!! test +External links: nowiki in URL link text (bug 6230) +!!input +[http://example.com/ <nowiki>''example site''</nowiki>] +!! result +<p><a rel="nofollow" class="external text" href="http://example.com/">''example site''</a> +</p> +!! end + +!! test +External links: newline forbidden in text (bug 6230 regression check) +!! input +[http://example.com/ first +second] +!! result +<p>[<a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> first +second] +</p> +!!end + +!! test +External links: Pipe char between url and text +!! input +[http://example.com | link] +!! result +<p><a rel="nofollow" class="external text" href="http://example.com">| link</a> +</p> +!!end + +!! test +External links: protocol-relative URL in brackets +!! input +[//example.com/ Test] +!! result +<p><a rel="nofollow" class="external text" href="//example.com/">Test</a> +</p> +!! end + +!! test +External links: protocol-relative URL in brackets without text +!! input +[//example.com] +!! result +<p><a rel="nofollow" class="external autonumber" href="//example.com">[1]</a> +</p> +!! end + +!! test +External links: protocol-relative URL in free text is left alone +!! input +//example.com/Foo +!! result +<p>//example.com/Foo +</p> +!!end + +!! test +External links: protocol-relative URL in the middle of a word is left alone (bug 30269) +!! input +foo//example.com/Foo +!! result +<p>foo//example.com/Foo +</p> +!! end + +!! test +External image +!! input +External image: http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png +!! result +<p>External image: <img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /> +</p> +!! end + +!! test +External image from https +!! input +External image from https: https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png +!! result +<p>External image from https: <img src="https://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /> +</p> +!! 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 +!! result +<p>Link to non-http image, no img tag: <a rel="nofollow" class="external free" href="ftp://example.com/test.jpg">ftp://example.com/test.jpg</a> +</p> +!! end + +!! test +External links: terminating separator +!! input +Terminating separator: http://example.com/thing, +!! result +<p>Terminating separator: <a rel="nofollow" class="external free" href="http://example.com/thing">http://example.com/thing</a>, +</p> +!! end + +!! test +External links: intervening separator +!! input +Intervening separator: http://example.com/1,2,3 +!! result +<p>Intervening separator: <a rel="nofollow" class="external free" href="http://example.com/1,2,3">http://example.com/1,2,3</a> +</p> +!! end + +!! test +External links: old bug with URL in query +!! input +Old bug with URL in query: [http://example.com/thing?url=http://example.com link] +!! result +<p>Old bug with URL in query: <a rel="nofollow" class="external text" href="http://example.com/thing?url=http://example.com">link</a> +</p> +!! end + +!! test +External links: old URL-in-URL bug, mixed protocols +!! input +And again with mixed protocols: [ftp://example.com?url=http://example.com link] +!! result +<p>And again with mixed protocols: <a rel="nofollow" class="external text" href="ftp://example.com?url=http://example.com">link</a> +</p> +!!end + +!! test +External links: URL in text +!! input +URL in text: [http://example.com http://example.com] +!! result +<p>URL in text: <a rel="nofollow" class="external free" href="http://example.com">http://example.com</a> +</p> +!! end + +!! test +External links: Clickable images +!! input +ja-style clickable images: [http://example.com http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png] +!! result +<p>ja-style clickable images: <a rel="nofollow" class="external text" href="http://example.com"><img src="http://meta.wikimedia.org/upload/f/f1/Ncwikicol.png" alt="Ncwikicol.png" /></a> +</p> +!!end + +!! test +External links: raw ampersand +!! input +Old & use: http://x&y +!! result +<p>Old & use: <a rel="nofollow" class="external free" href="http://x&y">http://x&y</a> +</p> +!! end + +!! test +External links: encoded ampersand +!! input +Old & use: http://x&y +!! result +<p>Old & use: <a rel="nofollow" class="external free" href="http://x&y">http://x&y</a> +</p> +!! end + +!! test +External links: encoded equals (bug 6102) +!! input +http://example.com/?foo=bar +!! result +<p><a rel="nofollow" class="external free" href="http://example.com/?foo=bar">http://example.com/?foo=bar</a> +</p> +!! end + +!! test +External links: [raw ampersand] +!! input +Old & use: [http://x&y] +!! result +<p>Old & use: <a rel="nofollow" class="external autonumber" href="http://x&y">[1]</a> +</p> +!! end + +!! test +External links: [encoded ampersand] +!! input +Old & use: [http://x&y] +!! result +<p>Old & use: <a rel="nofollow" class="external autonumber" href="http://x&y">[1]</a> +</p> +!! end + +!! test +External links: [encoded equals] (bug 6102) +!! input +[http://example.com/?foo=bar] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://example.com/?foo=bar">[1]</a> +</p> +!! end + +!! test +External links: [IDN ignored character reference in hostname; strip it right off] +!! input +[http://e‌xample.com/] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://example.com/">[1]</a> +</p> +!! end + +# FIXME: This test (the IDN characters in the text of a link) is an inconsistency. +# Where an external link could easily circumvent the sanitization of the text of +# a link like this (where an IDN-ignore character is in the URL somewhere), this +# test demands a higher standard. That's a bit strange. +# +# Example: +# +# http://example.com -> [http://example.com|http://example.com] +# [http://example.com|http://example.com] -> [http://example.com|http://example.com] +# +# The first example is sanitized, but the second is not. Any security benefits +# from this production are trivial to circumvent. Either remove this test and +# let the parser(s) do their thing unaccosted, or fix the inconsistency and change +# the test accordingly. +# +# All our love, +# The Parsoid team. +!! test +External links: IDN ignored character reference in hostname; strip it right off +!! input +http://e‌xample.com/ +!! result +<p><a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a> +</p> +!! end + +!! test +External links: www.jpeg.org (bug 554) +!! input +http://www.jpeg.org +!!result +<p><a rel="nofollow" class="external free" href="http://www.jpeg.org">http://www.jpeg.org</a> +</p> +!! end + +!! test +External links: URL within URL (original bug 2) +!! input +[http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp">[1]</a> +</p> +!! end + +!! test +BUG 361: URL inside bracketed URL +!! input +[http://www.example.com/foo http://www.example.com/bar] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/foo">http://www.example.com/bar</a> +</p> +!! end + +!! test +BUG 361: URL within URL, not bracketed +!! input +http://www.example.com/foo?=http://www.example.com/bar +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/foo?=http://www.example.com/bar">http://www.example.com/foo?=http://www.example.com/bar</a> +</p> +!! end + +!! test +BUG 289: ">"-token in URL-tail +!! input +http://www.example.com/<hello> +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/">http://www.example.com/</a><hello> +</p> +!!end + +!! test +BUG 289: literal ">"-token in URL-tail +!! input +http://www.example.com/<b>html</b> +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/">http://www.example.com/</a><b>html</b> +</p> +!!end + +!! test +BUG 289: ">"-token in bracketed URL +!! input +[http://www.example.com/<hello> stuff] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/"><hello> stuff</a> +</p> +!!end + +!! test +BUG 289: literal ">"-token in bracketed URL +!! input +[http://www.example.com/<b>html</b> stuff] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/"><b>html</b> stuff</a> +</p> +!!end + +!! test +BUG 289: literal double quote at end of URL +!! input +http://www.example.com/"hello" +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/">http://www.example.com/</a>"hello" +</p> +!!end + +!! test +BUG 289: literal double quote in bracketed URL +!! input +[http://www.example.com/"hello" stuff] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/">"hello" stuff</a> +</p> +!!end + +!! test +External links: multiple legal whitespace is fine, Magnus. Don't break it please. (bug 5081) +!! input +[http://www.example.com test] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com">test</a> +</p> +!! end + +!! test +External links: link text with spaces +!! input +[http://www.example.com a b c] +[http://www.example.com ''a'' ''b''] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com">a b c</a> +<a rel="nofollow" class="external text" href="http://www.example.com"><i>a</i> <i>b</i></a> +</p> +!! end + +!! test +External links: wiki links within external link (Bug 3695) +!! input +[http://example.com [[wikilink]] embedded in ext link] +!! result +<p><a rel="nofollow" class="external text" href="http://example.com"></a><a href="/index.php?title=Wikilink&action=edit&redlink=1" class="new" title="Wikilink (page does not exist)">wikilink</a><a rel="nofollow" class="external text" href="http://example.com"> embedded in ext link</a> +</p> +!! end + +!! test +BUG 787: Links with one slash after the url protocol are invalid +!! input +http:/example.com + +[http:/example.com title] +!! result +<p>http:/example.com +</p><p>[http:/example.com title] +</p> +!! end + +!! test +Bracketed external links with template-generated invalid target +!! input +[{{echo|http:/example.com}} title] +!! result +<p>[http:/example.com title] +</p> +!! end + +!! test +Bug 2702: Mismatched <i>, <b> and <a> tags are invalid +!! input +''[http://example.com text''] +[http://example.com '''text]''' +''Something [http://example.com in italic''] +''Something [http://example.com mixed''''', even bold]''' +'''''Now [http://example.com both'''''] +!! result +<p><a rel="nofollow" class="external text" href="http://example.com"><i>text</i></a> +<a rel="nofollow" class="external text" href="http://example.com"><b>text</b></a> +<i>Something </i><a rel="nofollow" class="external text" href="http://example.com"><i>in italic</i></a> +<i>Something </i><a rel="nofollow" class="external text" href="http://example.com"><i>mixed</i><b>, even bold</b></a> +<i><b>Now </b></i><a rel="nofollow" class="external text" href="http://example.com"><i><b>both</b></i></a> +</p> +!! end + + +!! test +Bug 4781: %26 in URL +!! input +http://www.example.com/?title=AT%26T +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/?title=AT%26T">http://www.example.com/?title=AT%26T</a> +</p> +!! end + +# According to http://dev.w3.org/html5/spec/Overview.html#parsing-urls a plain +# % is actually legal in HTML5. Any change in output would need testing though. +!! test +Bug 4781, 5267: %25 in URL +!! input +http://www.example.com/?title=100%25_Bran +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/?title=100%25_Bran">http://www.example.com/?title=100%25_Bran</a> +</p> +!! end + +!! test +Bug 4781, 5267: %28, %29 in URL +!! input +http://www.example.com/?title=Ben-Hur_%281959_film%29 +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.com/?title=Ben-Hur_%281959_film%29">http://www.example.com/?title=Ben-Hur_%281959_film%29</a> +</p> +!! end + + +!! test +Bug 4781: %26 in autonumber URL +!! input +[http://www.example.com/?title=AT%26T] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://www.example.com/?title=AT%26T">[1]</a> +</p> +!! end + +!! test +Bug 4781, 5267: %26 in autonumber URL +!! input +[http://www.example.com/?title=100%25_Bran] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://www.example.com/?title=100%25_Bran">[1]</a> +</p> +!! end + +!! test +Bug 4781, 5267: %28, %29 in autonumber URL +!! input +[http://www.example.com/?title=Ben-Hur_%281959_film%29] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://www.example.com/?title=Ben-Hur_%281959_film%29">[1]</a> +</p> +!! end + + +!! test +Bug 4781: %26 in bracketed URL +!! input +[http://www.example.com/?title=AT%26T link] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/?title=AT%26T">link</a> +</p> +!! end + +!! test +Bug 4781, 5267: %26 in bracketed URL +!! input +[http://www.example.com/?title=100%25_Bran link] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/?title=100%25_Bran">link</a> +</p> +!! end + +!! test +Bug 4781, 5267: %28, %29 in bracketed URL +!! input +[http://www.example.com/?title=Ben-Hur_%281959_film%29 link] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.com/?title=Ben-Hur_%281959_film%29">link</a> +</p> +!! end + +!! test +External link containing double-single-quotes in text '' (bug 4598 sanity check) +!! input +Some [http://example.com/ pretty ''italics'' and stuff]! +!! result +<p>Some <a rel="nofollow" class="external text" href="http://example.com/">pretty <i>italics</i> and stuff</a>! +</p> +!! end + +!! test +External link containing double-single-quotes in text embedded in italics (bug 4598 sanity check) +!! input +''Some [http://example.com/ pretty ''italics'' and stuff]!'' +!! result +<p><i>Some </i><a rel="nofollow" class="external text" href="http://example.com/"><i>pretty </i>italics<i> and stuff</i></a><i>!</i> +</p> +!! end + +!! test +External link containing double-single-quotes with no space separating the url from text in italics +!! input +[http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm''La muerte de Casagemas'' (1901) en el sitio de [[Museo Picasso (París)|Museo Picasso]].] +!! result +<p><a rel="nofollow" class="external text" href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm"><i>La muerte de Casagemas</i> (1901) en el sitio de <a href="/index.php?title=Museo_Picasso_(Par%C3%ADs)&action=edit&redlink=1" class="new" title="Museo Picasso (París) (page does not exist)">Museo Picasso</a>.</a> +</p> +!! 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=&}} +!! result +<p>/index.php?title=Some_page&amp=& +</p> +!! end + +!! test +URL-encoding in URL functions (multiple parameters) +!! input +{{localurl:Some page|q=?&=&}} +!! result +<p>/index.php?title=Some_page&q=?&amp=& +</p> +!! end + +!! test +Brackets in urls +!! input +http://example.com/index.php?foozoid%5B%5D=bar + +http://example.com/index.php?foozoid[]=bar +!! result +<p><a rel="nofollow" class="external free" href="http://example.com/index.php?foozoid%5B%5D=bar">http://example.com/index.php?foozoid%5B%5D=bar</a> +</p><p><a rel="nofollow" class="external free" href="http://example.com/index.php?foozoid%5B%5D=bar">http://example.com/index.php?foozoid%5B%5D=bar</a> +</p> +!! end + +!! test +IPv6 urls (bug 21261) +!! options +disabled +!! input +http://[2404:130:0:1000::187:2]/index.php +!! result +<p><a rel="nofollow" class="external free" href="http://[2404:130:0:1000::187:2]/index.php">http://[2404:130:0:1000::187:2]/index.php</a> +</p> +!! end + +!! test +Non-extlinks in brackets +!! input +[foo] +[foo bar] +[foo ''bar''] +[fool's] errand +[fool's errand] +[{{echo|foo}}] +[{{echo|foo}} bar] +[{{echo|foo}} ''bar''] +[{{echo|foo}}l's] errand +[{{echo|foo}}l's errand] +[url={{echo|foo}}] +[url=http://example.com] +!! result +<p>[foo] +[foo bar] +[foo <i>bar</i>] +[fool's] errand +[fool's errand] +[foo] +[foo bar] +[foo <i>bar</i>] +[fool's] errand +[fool's errand] +[url=foo] +[url=<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>] +</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 +### + +!! test +Quotes +!! input +Normal text. '''Bold text.''' Normal text. ''Italic text.'' + +Normal text. '''''Bold italic text.''''' Normal text. +!!result +<p>Normal text. <b>Bold text.</b> Normal text. <i>Italic text.</i> +</p><p>Normal text. <i><b>Bold italic text.</b></i> Normal text. +</p> +!! end + + +!! test +Unclosed and unmatched quotes (php) +!! options +php +!! 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). +</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 +# 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 +### +### some content taken from http://meta.wikimedia.org/wiki/MediaWiki_User%27s_Guide:_Using_tables +### + +# This should not produce <table></table> as <table><tr><td></td></tr></table> +# 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. (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 (php) +!! options +php +!! input +{| +|+ caption +|} +!! result +<table> +<caption> 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 +!! input +{| +|+ style="color: red;" | caption1 +|- +| foo +|} +!! result +<table> +<caption style="color: red;"> caption1 +</caption> +<tr> +<td> foo +</td></tr></table> + +!! end + +!! test +A table with captions with non-default spaced attributes and a table row +!! input +{| +|+style="color: red;"|caption2 +|+ style="color: red;"| caption3 +|- +| foo +|} +!! result +<table> +<caption style="color: red;">caption2 +</caption> +<caption style="color: red;"> caption3 +</caption> +<tr> +<td> foo +</td></tr></table> + +!! end + +!! test +Table td-cell syntax variations +!! input +{| +| foo bar foo | baz +| foo bar foo || baz +| style='color:red;' | baz +| style='color:red;' || baz +|} +!! result +<table> +<tr> +<td> baz +</td> +<td> foo bar foo </td> +<td> baz +</td> +<td style="color:red;"> baz +</td> +<td> style='color:red;' </td> +<td> baz +</td></tr></table> + +!! end + +!! test +Simple table +!! input +{| +| 1 || 2 +|- +| 3 || 4 +|} +!! result +<table> +<tr> +<td> 1 </td> +<td> 2 +</td></tr> +<tr> +<td> 3 </td> +<td> 4 +</td></tr></table> + +!! end + +!! test +Simple table but with multiple dashes for row wikitext +!! input +{| +| foo +|----- +| bar +|} +!! result +<table> +<tr> +<td> foo +</td></tr> +<tr> +<td> bar +</td></tr></table> + +!! end +!! test +Multiplication table +!! input +{| border="1" cellpadding="2" +|+Multiplication table +|- +! × !! 1 !! 2 !! 3 +|- +! 1 +| 1 || 2 || 3 +|- +! 2 +| 2 || 4 || 6 +|- +! 3 +| 3 || 6 || 9 +|- +! 4 +| 4 || 8 || 12 +|- +! 5 +| 5 || 10 || 15 +|} +!! result +<table border="1" cellpadding="2"> +<caption>Multiplication table +</caption> +<tr> +<th> × </th> +<th> 1 </th> +<th> 2 </th> +<th> 3 +</th></tr> +<tr> +<th> 1 +</th> +<td> 1 </td> +<td> 2 </td> +<td> 3 +</td></tr> +<tr> +<th> 2 +</th> +<td> 2 </td> +<td> 4 </td> +<td> 6 +</td></tr> +<tr> +<th> 3 +</th> +<td> 3 </td> +<td> 6 </td> +<td> 9 +</td></tr> +<tr> +<th> 4 +</th> +<td> 4 </td> +<td> 8 </td> +<td> 12 +</td></tr> +<tr> +<th> 5 +</th> +<td> 5 </td> +<td> 10 </td> +<td> 15 +</td></tr></table> + +!! end + +!! test +Accept "||" in table headings +!! input +{| +!h1 || h2 +|} +!! result +<table> +<tr> +<th>h1 </th> +<th> h2 +</th></tr></table> + +!! end + +!! test +Accept "||" in indented table headings +!! input +:{| +!h1 || h2 +|} +!! result +<dl><dd><table> +<tr> +<th>h1 </th> +<th> h2 +</th></tr></table></dd></dl> + +!! end + +!! test +Accept empty attributes in td/th cells (td/th cells starting with leading ||) +!! input +{| +!| h1 +|| a +|} +!! result +<table> +<tr> +<th> h1 +</th> +<td> a +</td></tr></table> + +!! end + +!!test +Accept "| !" at start of line in tables (ignore !-attribute) +!!input +{| +|- +| !style="color:red" | bar +|} +!!result +<table> + +<tr> +<td> bar +</td></tr></table> + +!!end + +!!test +Allow +/- in 2nd and later cells in a row, in 1st cell when td-attrs are present, or in 1st cell when there is a space between "|" and +/- +!!input +{| +|- +|style='color:red;'|+1 +|style='color:blue;'|-1 +|- +| 1 || 2 || 3 +| 1 ||+2 ||-3 +|- +| +1 +| -1 +|} +!!result +<table> + +<tr> +<td style="color:red;">+1 +</td> +<td style="color:blue;">-1 +</td></tr> +<tr> +<td> 1 </td> +<td> 2 </td> +<td> 3 +</td> +<td> 1 </td> +<td>+2 </td> +<td>-3 +</td></tr> +<tr> +<td> +1 +</td> +<td> -1 +</td></tr></table> + +!!end + +!! test +Table rowspan +!! input +{| border=1 +| Cell 1, row 1 +|rowspan=2| Cell 2, row 1 (and 2) +| Cell 3, row 1 +|- +| Cell 1, row 2 +| Cell 3, row 2 +|} +!! result +<table border="1"> +<tr> +<td> Cell 1, row 1 +</td> +<td rowspan="2"> Cell 2, row 1 (and 2) +</td> +<td> Cell 3, row 1 +</td></tr> +<tr> +<td> Cell 1, row 2 +</td> +<td> Cell 3, row 2 +</td></tr></table> + +!! end + +!! test +Nested table +!! input +{| border=1 +| α +| +{| bgcolor=#ABCDEF border=2 +|nested +|- +|table +|} +|the original table again +|} +!! result +<table border="1"> +<tr> +<td> α +</td> +<td> +<table bgcolor="#ABCDEF" border="2"> +<tr> +<td>nested +</td></tr> +<tr> +<td>table +</td></tr></table> +</td> +<td>the original table again +</td></tr></table> + +!! end + +!! test +Invalid attributes in table cell (bug 1830) +!! input +{| +|Cell:|broken +|} +!! result +<table> +<tr> +<td>broken +</td></tr></table> + +!! end + + +!! test +Table security: embedded pipes (http://lists.wikimedia.org/mailman/htdig/wikitech-l/2006-April/022293.html) +!! input +{| +| |[ftp://|x||]" onmouseover="alert(document.cookie)">test +!! result +<table> +<tr> +<td>[<a rel="nofollow" class="external free" href="ftp://%7Cx">ftp://%7Cx</a></td> +<td>]" onmouseover="alert(document.cookie)">test +</td> +</tr> +</table> + +!! end + + +!! test +Indented table markup mixed with indented pre content (proposed in bug 6200) +!! input + <table> + <tr> + <td> + Text that should be rendered preformatted + </td> + </tr> + </table> +!! result + <table> + <tr> + <td> +<pre>Text that should be rendered preformatted +</pre> + </td> + </tr> + </table> + +!! end + +!! test +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 + +!! test +Table with row followed by newlines and table heading +!! input +{| +|- + +! foo +|} +!! result +<table> + + +<tr> +<th> foo +</th></tr></table> + +!! 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 +parsoid +!! input +{| +| style=| hello +|} +!! result +<table> +<tbody> +<tr> +<td style=""> hello +</td></tr></tbody></table> + +!! end + +!! test +Wikitext table with a lot of comments +!! input +{| +<!-- c0 --> +| foo +<!-- c1 --> +|- <!-- c2 --> +<!-- c3 --> +|<!-- c4 --> +<!-- c5 --> +|} +!! result +<table> +<tr> +<td> foo +</td></tr> +<tr> +<td> +</td></tr></table> + +!! 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 +### +!! test +Plain link, capitalized +!! input +[[Main Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p> +!! end + +!! test +Plain link, uncapitalized +!! input +[[main Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">main Page</a> +</p> +!! end + +!! test +Piped link +!! input +[[Main Page|The Main Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">The Main Page</a> +</p> +!! 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]] +!! result +<p><a href="/index.php?title=Zigzagzogzagzig&action=edit&redlink=1" class="new" title="Zigzagzogzagzig (page does not exist)">Zigzagzogzagzig</a> +</p> +!! end + +!! test +Broken link with fragment +!! input +[[Zigzagzogzagzig#zug]] +!! result +<p><a href="/index.php?title=Zigzagzogzagzig&action=edit&redlink=1" class="new" title="Zigzagzogzagzig (page does not exist)">Zigzagzogzagzig#zug</a> +</p> +!! end + +!! test +Special page link with fragment +!! input +[[Special:Version#anchor]] +!! result +<p><a href="/wiki/Special:Version#anchor" title="Special:Version">Special:Version#anchor</a> +</p> +!! end + +!! test +Nonexistent special page link with fragment +!! input +[[Special:ThisNameWillHopefullyNeverBeUsed#anchor]] +!! result +<p><a href="/wiki/Special:ThisNameWillHopefullyNeverBeUsed" class="new" title="Special:ThisNameWillHopefullyNeverBeUsed (page does not exist)">Special:ThisNameWillHopefullyNeverBeUsed#anchor</a> +</p> +!! end + +!! test +Link with prefix +!! input +xxx[[main Page]], xxx[[Main Page]], Xxx[[main Page]] XXX[[main Page]], XXX[[Main Page]] +!! result +<p>xxx<a href="/wiki/Main_Page" title="Main Page">main Page</a>, xxx<a href="/wiki/Main_Page" title="Main Page">Main Page</a>, Xxx<a href="/wiki/Main_Page" title="Main Page">main Page</a> XXX<a href="/wiki/Main_Page" title="Main Page">main Page</a>, XXX<a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p> +!! end + +!! test +Link with suffix +!! input +[[Main Page]]xxx, [[Main Page]]XXX, [[Main Page]]!!! +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Pagexxx</a>, <a href="/wiki/Main_Page" title="Main Page">Main Page</a>XXX, <a href="/wiki/Main_Page" title="Main Page">Main Page</a>!!! +</p> +!! end + +!! article +prefixed article +!! text +Some text +!! endarticle + +!! test +Bug 43661: Piped links with identical prefixes +!! input +[[prefixed article|prefixed articles with spaces]] + +[[prefixed article|prefixed articlesaoeu]] + +[[Main Page|Main Page test]] +!! result +<p><a href="/wiki/Prefixed_article" title="Prefixed article">prefixed articles with spaces</a> +</p><p><a href="/wiki/Prefixed_article" title="Prefixed article">prefixed articlesaoeu</a> +</p><p><a href="/wiki/Main_Page" title="Main Page">Main Page test</a> +</p> +!! end + + +!! test +Link with HTML entity in suffix / tail +!! input +[[Main Page]]", [[Main Page]]a +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>", <a href="/wiki/Main_Page" title="Main Page">Main Page</a>a +</p> +!! end + +!! test +Link with 3 brackets +!! input +[[[main page]]] +!! result +<p>[[[main page]]] +</p> +!! end + +!! test +Piped link with 3 brackets +!! input +[[[main page|the main page]]] +!! result +<p>[[[main page|the main page]]] +</p> +!! end + +!! test +Link with multiple pipes +!! input +[[Main Page|The|Main|Page]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">The|Main|Page</a> +</p> +!! end + +!! test +Link to namespaces +!! input +[[Talk:Parser testing]], [[Meta:Disclaimers]] +!! result +<p><a href="/index.php?title=Talk:Parser_testing&action=edit&redlink=1" class="new" title="Talk:Parser testing (page does not exist)">Talk:Parser testing</a>, <a href="/index.php?title=Meta:Disclaimers&action=edit&redlink=1" class="new" title="Meta:Disclaimers (page does not exist)">Meta:Disclaimers</a> +</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 +[[Meta:Disclaimers|The disclaimers]] +!! result +<p><a href="/index.php?title=Meta:Disclaimers&action=edit&redlink=1" class="new" title="Meta:Disclaimers (page does not exist)">The disclaimers</a> +</p> +!! end + +!! test +Link containing } +!! input +[[Usually caused by a typo (oops}]] +!! result +<p>[[Usually caused by a typo (oops}]] +</p> +!! end + +!! test +Link containing % (not as a hex sequence) +!! input +[[7% Solution]] +!! result +<p><a href="/index.php?title=7%25_Solution&action=edit&redlink=1" class="new" title="7% Solution (page does not exist)">7% Solution</a> +</p> +!! end + +!! test +Link containing % as a single hex sequence interpreted to char +!! input +[[7%25 Solution]] +!! result +<p><a href="/index.php?title=7%25_Solution&action=edit&redlink=1" class="new" title="7% Solution (page does not exist)">7% Solution</a> +</p> +!!end + +!! test +Link containing % as a double hex sequence interpreted to hex sequence +!! input +[[7%2525 Solution]] +!! result +<p>[[7%2525 Solution]] +</p> +!!end + +!! test +Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors +Example for such a section: == < == +!! input +[[%23%3c]][[%23%3e]] +!! result +<p><a href="#.3C">#<</a><a href="#.3E">#></a> +</p> +!! end + +!! test +Link containing "<#" and ">#" as a hex sequences +!! input +[[%3c%23]][[%3e%23]] +!! result +<p>[[%3c%23]][[%3e%23]] +</p> +!! 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]] +!! result +<p><a href="/index.php?title=Lista_d%27%27e_paise_d%27%27o_munno&action=edit&redlink=1" class="new" title="Lista d''e paise d''o munno (page does not exist)">Lista d''e paise d''o munno</a> +</p> +!! end + +!! test +Link containing double-single-quotes '' in text (bug 4598 sanity check) +!! input +Some [[Link|pretty ''italics'' and stuff]]! +!! result +<p>Some <a href="/index.php?title=Link&action=edit&redlink=1" class="new" title="Link (page does not exist)">pretty <i>italics</i> and stuff</a>! +</p> +!! end + +!! test +Link containing double-single-quotes '' in text embedded in italics (bug 4598 sanity check) +!! input +''Some [[Link|pretty ''italics'' and stuff]]! +!! result +<p><i>Some <a href="/index.php?title=Link&action=edit&redlink=1" class="new" title="Link (page does not exist)">pretty <i>italics</i> and stuff</a>!</i> +</p> +!! end + +!! test +Link with double quotes in title part (literal) and alternate part (interpreted) +!! input +[[File:Denys Savchenko ''Pentecoste''.jpg]] + +[[''Pentecoste'']] + +[[''Pentecoste''|Pentecoste]] + +[[''Pentecoste''|''Pentecoste'']] +!! result +<p><a href="/index.php?title=Special:Upload&wpDestFile=Denys_Savchenko_%27%27Pentecoste%27%27.jpg" class="new" title="File:Denys Savchenko ''Pentecoste''.jpg">File:Denys Savchenko <i>Pentecoste</i>.jpg</a> +</p><p><a href="/index.php?title=%27%27Pentecoste%27%27&action=edit&redlink=1" class="new" title="''Pentecoste'' (page does not exist)">''Pentecoste''</a> +</p><p><a href="/index.php?title=%27%27Pentecoste%27%27&action=edit&redlink=1" class="new" title="''Pentecoste'' (page does not exist)">Pentecoste</a> +</p><p><a href="/index.php?title=%27%27Pentecoste%27%27&action=edit&redlink=1" class="new" title="''Pentecoste'' (page does not exist)"><i>Pentecoste</i></a> +</p> +!! end + +!! test +Broken image links with HTML captions (bug 39700) +!! input +[[File:Nonexistent|<script></script>]] +[[File:Nonexistent|100px|<script></script>]] +[[File:Nonexistent|<]] +[[File:Nonexistent|a<i>b</i>c]] +!! result +<p><a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><script></script></a> +<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><script></script></a> +<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent"><</a> +<a href="/index.php?title=Special:Upload&wpDestFile=Nonexistent" class="new" title="File:Nonexistent">abc</a> +</p> +!! end + +!! test +Plain link to URL +!! input +[[http://www.example.com]] +!! result +<p>[<a rel="nofollow" class="external autonumber" href="http://www.example.com">[1]</a>] +</p> +!! end + +!! test +Plain link to URL with link text +!! input +[[http://www.example.com Link text]] +!! result +<p>[<a rel="nofollow" class="external text" href="http://www.example.com">Link text</a>] +</p> +!! end + +!! test +Plain link to protocol-relative URL +!! input +[[//www.example.com]] +!! result +<p>[<a rel="nofollow" class="external autonumber" href="//www.example.com">[1]</a>] +</p> +!! end + +!! test +Plain link to protocol-relative URL with link text +!! input +[[//www.example.com Link text]] +!! result +<p>[<a rel="nofollow" class="external text" href="//www.example.com">Link text</a>] +</p> +!! end + +!! test +Plain link to page with question mark in title +!! input +[[A?b]] + +[[A?b|Baz]] +!! result +<p><a href="/wiki/A%3Fb" title="A?b">A?b</a> +</p><p><a href="/wiki/A%3Fb" title="A?b">Baz</a> +</p> +!! end + + +# I'm fairly sure the expected result here is wrong. +# We want these to be URL links, not pseudo-pages with URLs for titles.... +# However the current output is also pretty screwy. +# +# ---- +# I'm changing it to match the current output--it arguably makes more +# sense in the light of the test above. Old expected result was: +#<p>Piped link to URL: <a href="/index.php?title=Http://www.example.com&action=edit" class="new">an example URL</a> +#</p> +# But I think this test is bordering on "garbage in, garbage out" anyway. +# -- wtm +!! test +Piped link to URL +!! input +Piped link to URL: [[http://www.example.com|an example URL]] +!! result +<p>Piped link to URL: [<a rel="nofollow" class="external text" href="http://www.example.com%7Can">example URL</a>] +</p> +!! end + +!! test +BUG 2: [[page|http://url/]] should link to page, not http://url/ +!! input +[[Main Page|http://url/]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">http://url/</a> +</p> +!! end + +!! test +BUG 337: Escaped self-links should be bold +!! options +title=[[Bug462]] +!! input +[[Bug462]] [[Bug462]] +!! result +<p><strong class="selflink">Bug462</strong> <strong class="selflink">Bug462</strong> +</p> +!! end + +!! test +Self-link to section should not be bold +!! options +title=[[Main Page]] +!! input +[[Main Page#section]] +!! result +<p><a href="/wiki/Main_Page#section" title="Main Page">Main Page#section</a> +</p> +!! end + +!! article +00 +!! text +This is 00. +!! endarticle + +!!test +Self-link to numeric title +!!options +title=[[0]] +!!input +[[0]] +!!result +<p><strong class="selflink">0</strong> +</p> +!!end + +!!test +Link to numeric-equivalent title +!!options +title=[[0]] +!!input +[[00]] +!!result +<p><a href="/wiki/00" title="00">00</a> +</p> +!!end + +!! test +<nowiki> inside a link +!! input +[[Main<nowiki> Page</nowiki>]] [[Main Page|the main page <nowiki>[it's not very good]</nowiki>]] +!! result +<p>[[Main Page]] <a href="/wiki/Main_Page" title="Main Page">the main page [it's not very good]</a> +</p> +!! end + +!! test +Non-breaking spaces in title +!! input +[[ Main Page ]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">  Main   Page  </a> +</p> +!!end + +!! test +Internal link with ca linktrail, surrounded by bold apostrophes (bug 27473 primary issue) +!! options +language=ca +!! input +'''[[Main Page]]''' +!! result +<p><b><a href="/wiki/Main_Page" title="Main Page">Main Page</a></b> +</p> +!! end + +!! test +Internal link with ca linktrail, surrounded by italic apostrophes (bug 27473 primary issue) +!! options +language=ca +!! input +''[[Main Page]]'' +!! result +<p><i><a href="/wiki/Main_Page" title="Main Page">Main Page</a></i> +</p> +!! end + +!! test +Internal link with en linktrail: no apostrophes (bug 27473) +!! options +language=en +!! input +[[Something]]'nice +!! result +<p><a href="/index.php?title=Something&action=edit&redlink=1" class="new" title="Something (page does not exist)">Something</a>'nice +</p> +!! end + +!! test +Internal link with ca linktrail with apostrophes (bug 27473) +!! options +language=ca +!! input +[[Something]]'nice +!! result +<p><a href="/index.php?title=Something&action=edit&redlink=1" class="new" title="Something (encara no existeix)">Something'nice</a> +</p> +!! end + +!! test +Internal link with kaa linktrail with apostrophes (bug 27473) +!! options +language=kaa +!! input +[[Something]]'nice +!! result +<p><a href="/index.php?title=Something&action=edit&redlink=1" class="new" title="Something (bet ele jaratılmag'an)">Something'nice</a> +</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 +[[Foo| bar]] + +[[Foo| ''bar'']] + +[http://wp.org foo] + +[http://wp.org ''foo''] +!! result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)"> bar</a> +</p><p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)"> <i>bar</i></a> +</p><p><a rel="nofollow" class="external text" href="http://wp.org">foo</a> +</p><p><a rel="nofollow" class="external text" href="http://wp.org"><i>foo</i></a> +</p> +!! end + +### +### Interwiki links (see maintenance/interwiki.sql) +### + +!! test +Inline interwiki link +!! input +[[MeatBall:SoftSecurity]] +!! result +<p><a href="http://www.usemod.com/cgi-bin/mb.pl?SoftSecurity" class="extiw" title="meatball:SoftSecurity">MeatBall:SoftSecurity</a> +</p> +!! end + +!! test +Inline interwiki link with empty title (bug 2372) +!! input +[[MeatBall:]] +!! result +<p><a href="http://www.usemod.com/cgi-bin/mb.pl" class="extiw" title="meatball:">MeatBall:</a> +</p> +!! end + +!! test +Interwiki link encoding conversion (bug 1636) +!! input +*[[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> + +!! end + +!! test +Interwiki link with fragment (bug 2130) +!! input +[[MeatBall:SoftSecurity#foo]] +!! result +<p><a href="http://www.usemod.com/cgi-bin/mb.pl?SoftSecurity#foo" class="extiw" title="meatball:SoftSecurity">MeatBall:SoftSecurity#foo</a> +</p> +!! end + + +### +### Interlanguage links +### Language links (so that searching for '### language' matches..) +### + +!! test +Interlanguage link +!! input +Blah blah blah +[[zh:Chinese]] +!!result +<p>Blah blah blah +</p> +!! end + +!! test +Double interlanguage link +!! input +Blah blah blah +[[es:Spanish]] +[[zh:Chinese]] +!!result +<p>Blah blah blah +</p> +!! end + +!! test +Interlanguage link, with prefix links +!! options +language=ln +!! input +Blah blah blah +[[zh:Chinese]] +!!result +<p>Blah blah blah +</p> +!! end + +!! test +Double interlanguage link, with prefix links (bug 8897) +!! options +language=ln +!! input +Blah blah blah +[[es:Spanish]] +[[zh:Chinese]] +!!result +<p>Blah blah blah +</p> +!! end + +!! test +Parsoid-specific test: Wikilinks with should RT properly +!! options +language=ln +!! input +[[WW II]] +!!result +<p><a href="/index.php?title=WW_II&action=edit&redlink=1" class="new" title="WW II (lonkásá ezalí tɛ̂)">WW II</a> +</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 +### + +!! test +<br> to <br /> +!! input +1<br>2<br />3 +!! result +<p>1<br />2<br />3 +</p> +!! end + +!! test +Broken br tag sanitization +!! options +php +!! input +</br> +!! result +<p></br> +</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 +<br style="clear:both;" /> +!! result +<p><br style="clear:both;" /> +</p> +!! end + +!! test +Failing to transform badly formed HTML into correct XHTML +!! input +<br style="clear: left;"> +<br style="clear: right;"> +<br style="clear: both;"> +!! result +<p><br style="clear: left;" /> +<br style="clear: right;" /> +<br style="clear: both;" /> +</p> +!!end + +!! test +Handling html with a div self-closing tag +!! input +<div title /> +<div title/> +<div title/ > +<div title=bar /> +<div title=bar/> +<div title=bar/ > +!! result +<p><div title /> +<div title/> +</p> +<div> +<p><div title=bar /> +<div title=bar/> +</p> +<div title="bar/"></div> +</div> + +!! end + +!! test +Handling html with a br self-closing tag +!! input +<br title /> +<br title/> +<br title/ > +<br title=bar /> +<br title=bar/> +<br title=bar/ > +!! result +<p><br title="title" /> +<br title="title" /> +<br /> +<br title="bar" /> +<br title="bar" /> +<br title="bar/" /> +</p> +!! end + +!! test +Horizontal ruler (should it add that extra space?) +!! input +<hr> +<hr > +foo <hr +> bar +!! result +<hr /> +<hr /> +foo <hr /> bar + +!! end + +!! test +Horizontal ruler -- 4+ dashes render hr +!! input +---- +!! result +<hr /> + +!! end + +!! test +Horizontal ruler -- eats additional dashes on the same line +!! input +--------- +!! result +<hr /> + +!! end + +!! test +Horizontal ruler -- does not collapse dashes on consecutive lines +!! input +---- +---- +!! result +<hr /> +<hr /> + +!! end + +!! test +Horizontal ruler -- <4 dashes render as plain text +!! input +--- +!! result +<p>--- +</p> +!! end + +!! test +Horizontal ruler -- Supports content following dashes on same line +!! input +---- Foo +!! result +<hr /> Foo + +!! end + +### +### Block-level elements +### +!! test +Common list +!! input +*Common list +* item 2 +*item 3 +!! result +<ul> +<li>Common list +</li> +<li> item 2 +</li> +<li>item 3 +</li> +</ul> + +!! end + +!! test +Numbered list +!! input +#Numbered list +#item 2 +# item 3 +!! result +<ol> +<li>Numbered list +</li> +<li>item 2 +</li> +<li> item 3 +</li> +</ol> + +!! end + +!! test +Mixed list +!! input +*Mixed list +*# with numbers +** and bullets +*# and numbers +*bullets again +**bullet level 2 +***bullet level 3 +***#Number on level 4 +**bullet level 2 +**#Number on level 3 +**#Number on level 3 +*#number level 2 +*Level 1 +*** Level 3 +#** Level 3, but ordered +!! result +<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 + +!! test +Nested lists 1 +!! input +*foo +**bar +!! result +<ul> +<li>foo +<ul> +<li>bar +</li> +</ul> +</li> +</ul> + +!! end + +!! test +Nested lists 2 +!! input +**foo +*bar +!! result +<ul> +<li><ul> +<li>foo +</li> +</ul> +</li> +<li>bar +</li> +</ul> + +!! end + +!! test +Nested lists 3 (first element empty) +!! input +* +**bar +!! result +<ul> +<li> +<ul> +<li>bar +</li> +</ul> +</li> +</ul> + +!! end + +!! test +Nested lists 4 (first element empty) +!! input +** +*bar +!! result +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li>bar +</li> +</ul> + +!! end + +!! test +Nested lists 5 (both elements empty) +!! input +** +* +!! result +<ul> +<li><ul> +<li> +</li> +</ul> +</li> +<li> +</li> +</ul> + +!! end + +!! test +Nested lists 6 (both elements empty) +!! input +* +** +!! result +<ul> +<li> +<ul> +<li> +</li> +</ul> +</li> +</ul> + +!! end + +!! test +Nested lists 7 (skip initial nesting levels) +!! input +*** foo +!! result +<ul> +<li><ul> +<li><ul> +<li> foo +</li> +</ul> +</li> +</ul> +</li> +</ul> + +!! end + +!! test +Nested lists 8 (multiple nesting transitions) +!! input +* foo +*** bar +** baz +* boo +!! result +<ul> +<li> foo +<ul> +<li><ul> +<li> bar +</li> +</ul> +</li> +<li> baz +</li> +</ul> +</li> +<li> boo +</li> +</ul> + +!! end + +!! test +1. Lists with start-of-line-transparent tokens before bullets: Comments +!! input +*foo +*<!--cmt-->bar +<!--cmt-->*baz +!! result +<ul> +<li>foo +</li> +<li>bar +</li> +<li>baz +</li> +</ul> + +!! end + +!! test +2. Lists with start-of-line-transparent tokens before bullets: Template close +!! input +*foo {{echo|bar +}}*baz +!! result +<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 +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) +!! options +parsoid +!! input +<div> +*a</div><div> +*b</div> +!! result +<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 +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) +!! options +parsoid +!! input +<span> +*a</span><span> +*b</span> +!! result +<p><span></span> +</p> +<ul> +<li>a<span></span> +</li> +<li>b +</li> +</ul> +!! end + +!! test +Unclosed formatting tags that straddle lists are closed and reopened +(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up) +!! options +parsoid +!! input +# <s> a +# b </s> +!! result +<ol> +<li> <s> a </s> +</li> +<li> <s> b </s> +</li> +</ol> +!! end + +!!test +List embedded in a non-block tag +(Ugly Parsoid output -- worth fixing; Disabled for PHP parser since it relies on Tidy) +!! options +parsoid +!!input +<small> +* foo +</small> +!!result +<p><small></small></p> +<small> +<ul> +<li> foo</li> +</ul> +</small> +<p><small></small></p> +!!end + +!! test +Table with missing opening <tr> tag +!! options +parsoid=wt2html,wt2wt +!! input +<table> +<td>foo</td> +</tr> +</table> +!! result +<table> +<tr> +<td>foo</td> +</tr> +</table> +!! 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 +{{CURRENTDAY}} +!! result +<p>1 +</p> +!! end + +!! test +Magic Word: {{CURRENTDAY2}} +!! input +{{CURRENTDAY2}} +!! result +<p>01 +</p> +!! end + +!! test +Magic Word: {{CURRENTDAYNAME}} +!! input +{{CURRENTDAYNAME}} +!! result +<p>Thursday +</p> +!! end + +!! test +Magic Word: {{CURRENTDOW}} +!! input +{{CURRENTDOW}} +!! result +<p>4 +</p> +!! end + +!! test +Magic Word: {{CURRENTMONTH}} +!! input +{{CURRENTMONTH}} +!! result +<p>01 +</p> +!! end + +!! test +Magic Word: {{CURRENTMONTH1}} +!! input +{{CURRENTMONTH1}} +!! result +<p>1 +</p> +!! end + +!! test +Magic Word: {{CURRENTMONTHABBREV}} +!! input +{{CURRENTMONTHABBREV}} +!! result +<p>Jan +</p> +!! end + +!! test +Magic Word: {{CURRENTMONTHNAME}} +!! input +{{CURRENTMONTHNAME}} +!! result +<p>January +</p> +!! end + +!! test +Magic Word: {{CURRENTMONTHNAMEGEN}} +!! input +{{CURRENTMONTHNAMEGEN}} +!! result +<p>January +</p> +!! end + +!! test +Magic Word: {{CURRENTTIME}} +!! input +{{CURRENTTIME}} +!! result +<p>00:02 +</p> +!! end + +!! test +Magic Word: {{CURRENTHOUR}} +!! input +{{CURRENTHOUR}} +!! result +<p>00 +</p> +!! end + +!! test +Magic Word: {{CURRENTWEEK}} (@bug 4594) +!! input +{{CURRENTWEEK}} +!! result +<p>1 +</p> +!! end + +!! test +Magic Word: {{CURRENTYEAR}} +!! input +{{CURRENTYEAR}} +!! result +<p>1970 +</p> +!! 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]] +!! input +{{FULLPAGENAME}} +!! result +<p>User:Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{FULLPAGENAMEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{FULLPAGENAMEE}} +!! result +<p>User:%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! 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]] +!! input +{{NAMESPACE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{NAMESPACEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{NAMESPACEE}} +!! result +<p>User +</p> +!! end + +!! test +Magic Word: {{NAMESPACENUMBER}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{NAMESPACENUMBER}} +!! result +<p>2 +</p> +!! 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>4 +</p> +!! end + +!! test +Magic Word: {{PAGENAME}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{PAGENAME}} +!! result +<p>Ævar Arnfjörð Bjarmason +</p> +!! end + +!! test +Magic Word: {{PAGENAME}} with metacharacters +!! options +title=[['foo & bar = baz']] +!! input +''{{PAGENAME}}'' +!! result +<p><i>'foo & bar = baz'</i> +</p> +!! end + +!! test +Magic Word: {{PAGENAME}} with metacharacters (bug 26781) +!! options +title=[[*RFC 1234 http://example.com/]] +!! input +{{PAGENAME}} +!! result +<p>*RFC 1234 http://example.com/ +</p> +!! end + +!! test +Magic Word: {{PAGENAMEE}} +!! options +title=[[User:Ævar Arnfjörð Bjarmason]] +!! input +{{PAGENAMEE}} +!! result +<p>%C3%86var_Arnfj%C3%B6r%C3%B0_Bjarmason +</p> +!! end + +!! test +Magic Word: {{PAGENAMEE}} with metacharacters (bug 26781) +!! options +title=[[*RFC 1234 http://example.com/]] +!! input +{{PAGENAMEE}} +!! result +<p>*RFC_1234_http://example.com/ +</p> +!! end + +!! test +Magic Word: {{REVISIONID}} +!! input +{{REVISIONID}} +!! result +<p>1337 +</p> +!! end + +!! test +Magic Word: {{SCRIPTPATH}} +!! input +{{SCRIPTPATH}} +!! result +<p>/ +</p> +!! end + +!! test +Magic Word: {{STYLEPATH}} +!! input +{{STYLEPATH}} +!! result +<p>/skins +</p> +!! end + +!! test +Magic Word: {{SERVER}} +!! input +{{SERVER}} +!! result +<p><a rel="nofollow" class="external free" href="http://example.org">http://example.org</a> +</p> +!! end + +!! test +Magic Word: {{SERVERNAME}} +!! input +{{SERVERNAME}} +!! result +<p>example.org +</p> +!! end + +!! test +Magic Word: {{SITENAME}} +!! input +{{SITENAME}} +!! result +<p>MediaWiki +</p> +!! 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}} +!! result +<p>Talk +</p> +!! end + +!! test +Namespace 1 {{ns:01}} +!! input +{{ns:01}} +!! result +<p>Talk +</p> +!! end + +!! test +Namespace 0 {{ns:0}} (bug 4783) +!! input +{{ns:0}} +!! result + +!! end + +!! test +Namespace 0 {{ns:00}} (bug 4783) +!! input +{{ns:00}} +!! result + +!! end + +!! test +Namespace -1 {{ns:-1}} +!! input +{{ns:-1}} +!! result +<p>Special +</p> +!! end + +!! test +Namespace User {{ns:User}} +!! input +{{ns:User}} +!! result +<p>User +</p> +!! end + +!! test +Namespace User talk {{ns:User_talk}} +!! input +{{ns:User_talk}} +!! result +<p>User talk +</p> +!! end + +!! test +Namespace User talk {{ns:uSeR tAlK}} +!! input +{{ns:uSeR tAlK}} +!! result +<p>User talk +</p> +!! end + +!! test +Namespace File {{ns:File}} +!! input +{{ns:File}} +!! result +<p>File +</p> +!! end + +!! test +Namespace File {{ns:Image}} +!! input +{{ns:Image}} +!! result +<p>File +</p> +!! end + +!! test +Namespace (lang=de) Benutzer {{ns:User}} +!! options +language=de +!! input +{{ns:User}} +!! result +<p>Benutzer +</p> +!! end + +!! test +Namespace (lang=de) Benutzer Diskussion {{ns:3}} +!! options +language=de +!! input +{{ns:3}} +!! result +<p>Benutzer Diskussion +</p> +!! end + + +!! test +Urlencode +!! input +{{urlencode:hi world?!}} +{{urlencode:hi world?!|WIKI}} +{{urlencode:hi world?!|PATH}} +{{urlencode:hi world?!|QUERY}} +!! result +<p>hi+world%3F%21 +hi_world%3F! +hi%20world%3F%21 +hi+world%3F%21 +</p> +!! end + +### +### Magic links +### +!! test +Magic links: internal link to RFC (bug 479) +!! input +[[RFC 123]] +!! result +<p><a href="/index.php?title=RFC_123&action=edit&redlink=1" class="new" title="RFC 123 (page does not exist)">RFC 123</a> +</p> +!! end + +!! test +Magic links: RFC (bug 479) +!! input +RFC 822 +!! result +<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc822">RFC 822</a> +</p> +!! end + +!! test +Magic links: ISBN (bug 1937) +!! input +ISBN 0-306-40615-2 +!! result +<p><a href="/wiki/Special:BookSources/0306406152" class="internal mw-magiclink-isbn">ISBN 0-306-40615-2</a> +</p> +!! end + +!! test +Magic links: PMID incorrectly converts space to underscore +!! input +PMID 1234 +!! result +<p><a class="external mw-magiclink-pmid" rel="nofollow" href="//www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract">PMID 1234</a> +</p> +!! end + +### +### Templates +#### + +!! test +Nonexistent template +!! input +{{thistemplatedoesnotexist}} +!! result +<p><a href="/index.php?title=Template:Thistemplatedoesnotexist&action=edit&redlink=1" class="new" title="Template:Thistemplatedoesnotexist (page does not exist)">Template:Thistemplatedoesnotexist</a> +</p> +!! end + +!! test +Template with invalid target containing tags +!! input +{{a<b>b</b>|{{echo|foo}}|{{echo|a}}={{echo|b}}|a = b}} +!! result +<p>{{a<b>b</b>|foo|a=b|a = b}} +</p> +!! end + +!! test +Template with invalid target containing unclosed tag +!! input +{{a<b>|{{echo|foo}}|{{echo|a}}={{echo|b}}|a = b}} +!! result +<p>{{a<b>|foo|a=b|a = b}}</b> +</p> +!! end + +!! article +Template:test +!! text +This is a test template +!! endarticle + +!! test +Simple template +!! input +{{test}} +!! result +<p>This is a test template +</p> +!! end + +!! test +Template with explicit namespace +!! input +{{Template:test}} +!! result +<p>This is a test template +</p> +!! end + + +!! article +Template:paramtest +!! text +This is a test template with parameter {{{param}}} +!! endarticle + +!! test +Template parameter +!! input +{{paramtest|param=foo}} +!! result +<p>This is a test template with parameter foo +</p> +!! end + +!! article +Template:paramtestnum +!! text +[[{{{1}}}|{{{2}}}]] +!! endarticle + +!! test +Template unnamed parameter +!! input +{{paramtestnum|Main Page|the main page}} +!! result +<p><a href="/wiki/Main_Page" title="Main Page">the main page</a> +</p> +!! end + +!! article +Template:templatesimple +!! text +(test) +!! endarticle + +!! article +Template:templateredirect +!! text +#redirect [[Template:templatesimple]] +!! endarticle + +!! article +Template:templateasargtestnum +!! text +{{{{{1}}}}} +!! endarticle + +!! article +Template:templateasargtest +!! text +{{template{{{templ}}}}} +!! endarticle + +!! article +Template:templateasargtest2 +!! text +{{{{{templ}}}}} +!! endarticle + +!! test +Template with template name as unnamed argument +!! input +{{templateasargtestnum|templatesimple}} +!! result +<p>(test) +</p> +!! end + +!! test +Template with template name as argument +!! input +{{templateasargtest|templ=simple}} +!! result +<p>(test) +</p> +!! end + +!! test +Template with template name as argument (2) +!! input +{{templateasargtest2|templ=templatesimple}} +!! result +<p>(test) +</p> +!! end + +!! article +Template:templateasargtestdefault +!! text +{{{{{templ|templatesimple}}}}} +!! endarticle + +!! article +Template:templa +!! text +'''templ''' +!! endarticle + +!! test +Template with default value +!! input +{{templateasargtestdefault}} +!! result +<p>(test) +</p> +!! end + +!! test +Template with default value (value set) +!! input +{{templateasargtestdefault|templ=templa}} +!! result +<p><b>templ</b> +</p> +!! end + +!! test +Template redirect +!! input +{{templateredirect}} +!! result +<p>(test) +</p> +!! end + +!! test +Template with argument in separate line +!! input +{{ templateasargtest | + templ = simple }} +!! result +<p>(test) +</p> +!! end + +!! test +Template with complex template as argument +!! input +{{paramtest| + param ={{ templateasargtest | + templ = simple }}}} +!! result +<p>This is a test template with parameter (test) +</p> +!! end + +!! test +Template with thumb image (with link in description) +!! input +{{paramtest| + param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}} +!! result +This is a test template with parameter <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a> <div class="thumbcaption"><a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&action=edit&redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div> + +!! end + +!! article +Template:complextemplate +!! text +{{{1}}} {{paramtest| + param ={{{param}}}}} +!! endarticle + +!! test +Template with complex arguments +!! input +{{complextemplate| + param ={{ templateasargtest | + templ = simple }}|[[Template:complextemplate|link]]}} +!! result +<p><a href="/wiki/Template:Complextemplate" title="Template:Complextemplate">link</a> This is a test template with parameter (test) +</p> +!! end + +!! test +BUG 553: link with two variables in a piped link +!! input +{| +|[[{{{1}}}|{{{2}}}]] +|} +!! result +<table> +<tr> +<td>[[{{{1}}}|{{{2}}}]] +</td></tr></table> + +!! end + +!! test +Magic variable as template parameter +!! input +{{paramtest|param={{SITENAME}}}} +!! result +<p>This is a test template with parameter MediaWiki +</p> +!! end + +!! article +Template:linktest +!! text +[[{{{param}}}|link]] +!! endarticle + +!! test +Template parameter as link source +!! input +{{linktest|param=Main Page}} +!! result +<p><a href="/wiki/Main_Page" title="Main Page">link</a> +</p> +!! end + +!!test +Template-generated attribute string (k='v') +!!input +<span {{attr_str|id|v1}}>bar</span> +!!result +<p><span id="v1">bar</span> +</p> +!!end + +!!article +Template:paramtest2 +!! text +including another template, {{paramtest|param={{{arg}}}}} +!! endarticle + +!! test +Template passing argument to another template +!! input +{{paramtest2|arg='hmm'}} +!! result +<p>including another template, This is a test template with parameter 'hmm' +</p> +!! end + +!! article +Template:Linktest2 +!! text +Main Page +!! endarticle + +!! test +Template as link source +!! input +[[{{linktest2}}]] + +[[{{linktest2}}|Main Page]] + +[[{{linktest2}}]]Page +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p><p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p><p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>Page +</p> +!! end + + +!! article +Template:loop1 +!! text +{{loop2}} +!! endarticle + +!! article +Template:loop2 +!! text +{{loop1}} +!! endarticle + +!! test +Template infinite loop +!! input +{{loop1}} +!! result +<p><span class="error">Template loop detected: <a href="/wiki/Template:Loop1" title="Template:Loop1">Template:Loop1</a></span> +</p> +!! end + +!! test +Template from main namespace +!! input +{{:Main Page}} +!! result +<p>blah blah +</p> +!! end + +!! article +Template:table +!! text +{| +| 1 || 2 +|- +| 3 || 4 +|} +!! endarticle + +!! test +BUG 529: Template with table, not included at beginning of line +!! input +foo {{table}} +!! result +<p>foo +</p> +<table> +<tr> +<td> 1 </td> +<td> 2 +</td></tr> +<tr> +<td> 3 </td> +<td> 4 +</td></tr></table> + +!! end + +!! test +BUG 523: Template shouldn't eat newline (or add an extra one before table) +!! input +foo +{{table}} +!! result +<p>foo +</p> +<table> +<tr> +<td> 1 </td> +<td> 2 +</td></tr> +<tr> +<td> 3 </td> +<td> 4 +</td></tr></table> + +!! end + +!! test +BUG 41: Template parameters shown as broken links +!! input +{{{parameter}}} +!! result +<p>{{{parameter}}} +</p> +!! end + +!! test +Template with targets containing wikilinks +!! input +{{[[foo]]}} + +{{[[{{echo|foo}}]]}} + +{{{{echo|[[foo}}]]}} +!! result +<p>{{<a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">foo</a>}} +</p><p>{{<a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">foo</a>}} +</p><p>{{[[foo}}]] +</p> +!! end + +!! article +Template:MSGNW test +!! text +''None'' of '''this''' should be +* interpreted + but rather passed unmodified +{{test}} +!! endarticle + +# hmm, fix this or just deprecate msgnw and document its behavior? +!! test +msgnw keyword +!! options +disabled +!! input +{{msgnw:MSGNW test}} +!! result +<p>''None'' of '''this''' should be +* interpreted + but rather passed unmodified +{{test}} +</p> +!! end + +!! test +int keyword +!! input +{{int:youhavenewmessages|lots of money|not!}} +!! result +<p>You have lots of money (not!). +</p> +!! end + +!! article +Template:Includes +!! text +Foo<noinclude>zar</noinclude><includeonly>bar</includeonly> +!! endarticle + +!! test +<includeonly> and <noinclude> being included +!! input +{{Includes}} +!! result +<p>Foobar +</p> +!! end + +!! article +Template:Includes2 +!! text +<onlyinclude>Foo</onlyinclude>bar +!! endarticle + +!! test +<onlyinclude> being included +!! input +{{Includes2}} +!! result +<p>Foo +</p> +!! end + + +!! article +Template:Includes3 +!! text +<onlyinclude>Foo</onlyinclude>bar<includeonly>zar</includeonly> +!! endarticle + +!! test +<onlyinclude> and <includeonly> being included +!! input +{{Includes3}} +!! result +<p>Foo +</p> +!! end + +!! test +<includeonly> and <noinclude> on a page +!! input +Foo<noinclude>zar</noinclude><includeonly>bar</includeonly> +!! result +<p>Foozar +</p> +!! end + +!! test +Un-closed <noinclude> +!! input +<noinclude> +!! result +!! end + +!! test +<onlyinclude> on a page +!! input +<onlyinclude>Foo</onlyinclude>bar +!! result +<p>Foobar +</p> +!! end + +!! test +Un-closed <onlyinclude> +!! input +<onlyinclude> +!! result +!! end + +!!test +Self-closed noinclude, includeonly, onlyinclude tags +!!input +<noinclude /> +<includeonly /> +<onlyinclude /> +!!result +<p><br /> +</p> +!!end + +!!test +Unbalanced includeonly and noinclude tags +!!input +{| +|a</noinclude> +|b</noinclude></noinclude> +|c</noinclude></includeonly> +|d</includeonly></includeonly> +|} +!!result +<table> +<tr> +<td>a +</td> +<td>b +</td> +<td>c</includeonly> +</td> +<td>d</includeonly></includeonly> +</td></tr></table> + +!!end + +!! article +Template:Includeonly section +!! text +<includeonly> +==Includeonly section== +</includeonly> +==Section T-1== +!!endarticle + +!! test +Bug 6563: Edit link generation for section shown by <includeonly> +!! input +{{includeonly section}} +!! result +<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 + +# Uses same input as the contents of [[Template:Includeonly section]] +!! test +Bug 6563: Section extraction for section shown by <includeonly> +!! options +section=T-2 +!! input +<includeonly> +==Includeonly section== +</includeonly> +==Section T-2== +!! result +==Section T-2== +!! end + +!! test +Bug 6563: Edit link generation for section suppressed by <includeonly> +!! input +<includeonly> +==Includeonly section== +</includeonly> +==Section 1== +!! result +<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 + +!! test +Bug 6563: Section extraction for section suppressed by <includeonly> +!! options +section=1 +!! input +<includeonly> +==Includeonly section== +</includeonly> +==Section 1== +!! result +==Section 1== +!! end + +!! test +Un-closed <includeonly> +!! input +<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 +### +!!test +0. includeonly around the entire attribute +!!input +<span <includeonly>id="v1"</includeonly><noinclude>id="v2"</noinclude>>bar</span> +!!result +<p><span id="v2">bar</span> +</p> +!!end + +!!test +1. includeonly in html attr key +!!input +<span <noinclude>id</noinclude><includeonly>about</includeonly>="foo">bar</span> +!!result +<p><span id="foo">bar</span> +</p> +!!end + +!!test +2. includeonly in html attr value +!!input +<span id="<noinclude>v1</noinclude><includeonly>v2</includeonly>">bar</span> +<span id=<noinclude>"v1"</noinclude><includeonly>"v2"</includeonly>>bar</span> +!!result +<p><span id="v1">bar</span> +<span id="v1">bar</span> +</p> +!!end + +!!test +3. includeonly in part of an attr value +!!input +<span style="color:<noinclude>red</noinclude><includeonly>blue</includeonly>;">bar</span> +!!result +<p><span style="color:red;">bar</span> +</p> +!!end + +### +### Testing parsing of templates where a template arg +### has the same name as the template itself. +### + +!! article +Template:quote +!! text +{{{quote|{{{1}}}}}} +!! endarticle + +!!test +Templates: Template Name/Arg clash: 1. Use of positional param +!!input +{{quote|foo}} +!!result +<p>foo +</p> +!!end + +!!test +Templates: Template Name/Arg clash: 2. Use of named param +!!input +{{quote|quote=foo}} +!!result +<p>foo +</p> +!!end + +!!test +Templates: Template Name/Arg clash: 3. Use of named param with empty input +!!input +{{quote|quote}} +!!result +<p>quote +</p> +!!end + +### +### Parsoid-centric tests to stress Parsoid's ability to RT them unchanged +### + +!!test +Templates: 1. Simple use +!!input +{{echo|Foo}} +!!result +<p>Foo +</p> +!!end + +!!test +Templates: 2. Inside a block tag +!!input +<div>{{echo|Foo}}</div> +<blockquote>{{echo|Foo}}</blockquote> +!!result +<div>Foo</div> +<blockquote>Foo</blockquote> + +!!end + +!!test +Templates: P-wrapping: 1a. Templates on consecutive lines +!!input +{{echo|Foo}} +{{echo|bar}} +!!result +<p>Foo +bar +</p> +!!end + +!!test +Templates: P-wrapping: 1b. Templates on consecutive lines +!!input +Foo + +{{echo|bar}} +{{echo|baz}} +!!result +<p>Foo +</p><p>bar +baz +</p> +!!end + +!!test +Templates: P-wrapping: 1c. Templates on consecutive lines +!!input +{{echo|Foo}} +{{echo|bar}} <div>baz</div> +!!result +<p>Foo +</p> +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}} +!!result +<p>Foobarbaz +</p> +!!end + +!!test +Templates: Inline Text: 2. Back-to-back template uses +!!input +{{echo|Foo}}{{echo|bar}} +!!result +<p>Foobar +</p> +!!end + +!!test +Templates: Block Tags: 1. Multiple template uses +!!input +{{echo|<div>Foo</div>}}<div>bar</div>{{echo|<div>baz</div>}} +!!result +<div>Foo</div><div>bar</div><div>baz</div> + +!!end + +!!test +Templates: Block Tags: 2. Back-to-back template uses +!!input +{{echo|<div>Foo</div>}}{{echo|<div>bar</div>}} +!!result +<div>Foo</div><div>bar</div> + +!!end + +!!test +Templates: Links: 1. Simple example +!!input +{{echo|[[Foo|bar]]}} +!!result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">bar</a> +</p> +!!end + +!!test +Templates: Links: 2. Generation of link href +!!input +[[{{echo|Foo}}|bar]] +!!result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">bar</a> +</p> +!!end + +!!test +Templates: Links: 3. Generation of part of a link href +!!input +[[Fo{{echo|o}}|bar]] + +[[Foo{{echo|bar}}]] + +[[Foo{{echo|bar}}baz]] + +[[Foo{{echo|bar}}|bar]] + +[[:Foo{{echo|bar}}]] + +[[:Foo{{echo|bar}}|bar]] +!!result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">bar</a> +</p><p><a href="/index.php?title=Foobar&action=edit&redlink=1" class="new" title="Foobar (page does not exist)">Foobar</a> +</p><p><a href="/index.php?title=Foobarbaz&action=edit&redlink=1" class="new" title="Foobarbaz (page does not exist)">Foobarbaz</a> +</p><p><a href="/index.php?title=Foobar&action=edit&redlink=1" class="new" title="Foobar (page does not exist)">bar</a> +</p><p><a href="/index.php?title=Foobar&action=edit&redlink=1" class="new" title="Foobar (page does not exist)">Foobar</a> +</p><p><a href="/index.php?title=Foobar&action=edit&redlink=1" class="new" title="Foobar (page does not exist)">bar</a> +</p> +!!end + +!!test +Templates: Links: 4. Multiple templates generating link href +!!input +[[{{echo|F}}{{echo|o}}ob{{echo|ar}}]] +!!result +<p><a href="/index.php?title=Foobar&action=edit&redlink=1" class="new" title="Foobar (page does not exist)">Foobar</a> +</p> +!!end + +!!test +Templates: Links: 5. Generation of link text +!!input +[[Foo|{{echo|bar}}]] +!!result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">bar</a> +</p> +!!end + +!!test +Templates: Links: 5. Nested templates (only outermost template should be marked) +!!input +{{echo|[[{{echo|Foo}}|bar]]}} +!!result +<p><a href="/index.php?title=Foo&action=edit&redlink=1" class="new" title="Foo (page does not exist)">bar</a> +</p> +!!end + +!!test +Templates: HTML Tag: 1. Generation of HTML attr. key +!!input +<div {{echo|style}}="color:red;">foo</div> +!!result +<div style="color:red;">foo</div> + +!!end + +!!test +Templates: HTML Tag: 2. Generation of HTML attr. value +!!input +<div style={{echo|'color:red;'}}>foo</div> +!!result +<div style="color:red;">foo</div> + +!!end + +!!test +Templates: HTML Tag: 3. Generation of HTML attr key and value +!!input +<div {{echo|style}}={{echo|'color:red;'}}>foo</div> +!!result +<div style="color:red;">foo</div> + +!!end + +!!test +Templates: HTML Tag: 4. Generation of starting piece of HTML attr value +!!input +<div title="{{echo|This is a long title}} with just one piece templated">foo</div> +!!result +<div title="This is a long title with just one piece templated">foo</div> + +!!end + +!!test +Templates: HTML Tag: 5. Generation of middle piece of HTML attr value +!!input +<div title="This is a long title with just {{echo|one piece}} templated">foo</div> +!!result +<div title="This is a long title with just one piece templated">foo</div> + +!!end + +!!test +Templates: HTML Tag: 6. Generation of end piece of HTML attr value +!!input +<div title="This is a long title with just one piece {{echo|templated}}">foo</div> +!!result +<div title="This is a long title with just one piece templated">foo</div> + +!!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> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 2a. Generating middle of a HTML table +!!input +<table><tr>{{echo|<td>foo</td>}}</tr></table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 2b. Generating middle of a HTML table +!!input +<table>{{echo|<tr><td>foo</td></tr>}}</table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 3. Generating end of a HTML table +!!input +<table><tr>{{echo|<td>foo</td></tr></table>}} +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4a. Generating a single tag of a HTML table +!!input +{{echo|<table>}}<tr><td>foo</td></tr></table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4b. Generating a single tag of a HTML table +!!input +<table>{{echo|<tr>}}<td>foo</td></tr></table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4c. Generating a single tag of a HTML table +!!input +<table><tr>{{echo|<td>}}foo</td></tr></table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4d. Generating a single tag of a HTML table +!!input +<table><tr><td>foo{{echo|</td>}}</tr></table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4e. Generating a single tag of a HTML table +!!input +<table><tr><td>foo</td>{{echo|</tr>}}</table> +!!result +<table><tr><td>foo</td></tr></table> + +!!end + +!!test +Templates: HTML Tables: 4f. Generating a single tag of a HTML table +!!input +<table><tr><td>foo</td></tr>{{echo|</table>}} +!!result +<table><tr><td>foo</td></tr></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 +{| +{{echo|a}} +|} +!!result +<table> +a +<tr><td></td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 1b. Fostering of entire template content +!!input +{| +{{echo|<div>}} +foo +{{echo|</div>}} +|} +!!result +<table> +<div> +<p>foo +</p> +</div> +<tr><td></td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 2. Fostering of partial template content +!!input +{| +{{echo|a +<div>b</div>}} +|} +!!result +<table> +a +<div>b</div> +<tr><td></td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 3. td-content via multiple templates +!!input +{| +{{echo|{{pipe}}a}}{{echo|b}} +|} +!!result +<table> +<tr> +<td>ab +</td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 4. Templated tags, no content +!!input +{{tbl-start}} +{{tbl-end}} +!!result +<table> +<tr><td></td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 5. Templated tags, regular td-tags +!!input +{{tbl-start}} +|foo +{{tbl-end}} +!!result +<table> +<tr> +<td>foo +</td></tr></table> + +!!end + +!!test +Templates: Wiki Tables: 6. Templated tags, templated td-tags +!!input +{{tbl-start}} +{{!}}foo +{{tbl-end}} +!!result +<table> +<tr> +<td>foo +</td></tr></table> + +!!end + +!!test +Templates: Lists: Multi-line list-items via templates +!!input +*{{echo|a {{nonexistent| +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> + +!!end + +!!test +Templates: Ugly nesting: 1. Quotes opened/closed across templates (echo) +!!input +{{echo|''a}}{{echo|b''c''d}}{{echo|''e}} +!!result +<p><i>ab</i>c<i>d</i>e +</p> +!!end + +!!test +Templates: Ugly nesting: 2. Quotes opened/closed across templates (echo_with_span) +(PHP parser generates misnested html) +!! options +parsoid +!!input +{{echo_with_span|''a}}{{echo_with_span|b''c''d}}{{echo_with_span|''e}} +!!result +<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; Parsoid html2wt mode adds newlines between {{echo}}s) +!! options +parsoid=wt2html,wt2wt +!!input +{{echo_with_div|''a}}{{echo_with_div|b''c''d}}{{echo_with_div|''e}} +!!result +<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 +Templates: Ugly nesting: 4. Divs opened/closed across templates +!!input +a<div>b{{echo|c</div>d}}e +!!result +a<div>bc</div>de + +!!end + +!!test +Templates: Ugly templates: 1. Navbox template parses badly leading to table misnesting +(Parsoid-centric) +!! options +parsoid +!!input +{| +|{{echo|foo</table>}} +|bar +|} +!!result +<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 + +!!test +Templates: Ugly templates: 2. Navbox template parses badly leading to table misnesting +(Parsoid-centric) +!! options +parsoid +!!input +<table> + <tr> + <td> + <table> + <tr> + <td>1. {{echo|foo </table>}}</td> + <td> bar </td> + <td>2. {{echo|baz </table>}}</td> + </tr> + <tr> + <td>abc</td> + </tr> + </table> + </td> + </tr> + <tr> + <td>xyz</td> + </tr> +</table> +!!result +<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 + +!! test +Templates: Ugly templates: 3. newline-only template parameter +!! input +foo {{echo| +}} +!! result +<p>foo +</p> +!! end + +# This looks like a bug: a single newline triggers p/br for some reason. +!! test +Templates: Ugly templates: 4. newline-only template parameter inconsistency +!! input +{{echo| +}} +!! result +<p><br /> +</p> +!! end + + +!!test +Parser Functions: 1. Simple example +!!input +{{uc:foo}} +!!result +<p>FOO +</p> +!!end + +!!test +Parser Functions: 2. Nested use (only outermost should be marked up) +!!input +{{uc:{{lc:FOO}}}} +!!result +<p>FOO +</p> +!!end + +### +### Pre-save transform tests +### +!! test +pre-save transform: subst: +!! options +PST +!! input +{{subst:test}} +!! result +This is a test template +!! end + +!! test +pre-save transform: normal template +!! options +PST +!! input +{{test}} +!! result +{{test}} +!! end + +!! test +pre-save transform: nonexistent template +!! options +PST +!! input +{{thistemplatedoesnotexist}} +!! result +{{thistemplatedoesnotexist}} +!! end + + +!! test +pre-save transform: subst magic variables +!! options +PST +!! input +{{subst:SITENAME}} +!! result +MediaWiki +!! end + +# This is bug 89, which I fixed. -- wtm +!! test +pre-save transform: subst: templates with parameters +!! options +pst +!! input +{{subst:paramtest|param="something else"}} +!! result +This is a test template with parameter "something else" +!! end + +!! article +Template:nowikitest +!! text +<nowiki>'''not wiki'''</nowiki> +!! endarticle + +!! test +pre-save transform: nowiki in subst (bug 1188) +!! options +pst +!! input +{{subst:nowikitest}} +!! result +<nowiki>'''not wiki'''</nowiki> +!! end + + +!! article +Template:commenttest +!! text +This template has <!-- a comment --> in it. +!! endarticle + +!! test +pre-save transform: comment in subst (bug 1936) +!! options +pst +!! input +{{subst:commenttest}} +!! result +This template has <!-- a comment --> in it. +!! end + +!! test +pre-save transform: unclosed tag +!! options +pst noxml +!! input +<nowiki>'''not wiki''' +!! result +<nowiki>'''not wiki''' +!! end + +!! test +pre-save transform: mixed tag case +!! options +pst noxml +!! input +<NOwiki>'''not wiki'''</noWIKI> +!! result +<NOwiki>'''not wiki'''</noWIKI> +!! end + +!! test +pre-save transform: unclosed comment in <nowiki> +!! options +pst noxml +!! input +wiki<nowiki>nowiki<!--nowiki</nowiki>wiki +!! result +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> +!!endarticle + +!!test +(confirming safety of fix for subst bug 1936) +!! input +{{Template:dangerous}} +!! result +<p>@<span>Oh no</span> +</p> +!! end + +!! test +pre-save transform: comment containing gallery (bug 5024) +!! options +pst +!! input +<!-- <gallery>data</gallery> --> +!!result +<!-- <gallery>data</gallery> --> +!!end + +!! test +pre-save transform: comment containing extension +!! options +pst +!! input +<!-- <tag>data</tag> --> +!!result +<!-- <tag>data</tag> --> +!!end + +!! test +pre-save transform: comment containing nowiki +!! options +pst +!! input +<!-- <nowiki>data</nowiki> --> +!!result +<!-- <nowiki>data</nowiki> --> +!!end + +!! test +pre-save transform: <noinclude> in subst (bug 3298) +!! options +pst +!! input +{{subst:Includes}} +!! result +Foobar +!! end + +!! test +pre-save transform: <onlyinclude> in subst (bug 3298) +!! options +pst +!! input +{{subst:Includes2}} +!! result +Foo +!! end + +!! article +Template:SubstTest +!!text +{{<includeonly>subst:</includeonly>Includes}} +!! endarticle + +!! article +Template:SafeSubstTest +!! text +{{<includeonly>safesubst:</includeonly>Includes}} +!! endarticle + +!! test +bug 22297: safesubst: works during PST +!! options +pst +!! input +{{subst:SafeSubstTest}}{{safesubst:SubstTest}} +!! result +FoobarFoobar +!! end + +!! test +bug 22297: safesubst: works during normal parse +!! input +{{SafeSubstTest}} +!! result +<p>Foobar +</p> +!! end + +!! test: +subst: does not work during normal parse +!! input +{{SubstTest}} +!! result +<p>{{subst:Includes}} +</p> +!! end + +!! test +pre-save transform: context links ("pipe trick") +!! options +pst +!! input +[[Article (context)|]] +[[Bar:Article|]] +[[:Bar:Article|]] +[[Bar:Article (context)|]] +[[:Bar:Article (context)|]] +[[|Article]] +[[|Article (context)]] +[[Bar:X (Y) Z|]] +[[:Bar:X (Y) Z|]] +!! result +[[Article (context)|Article]] +[[Bar:Article|Article]] +[[:Bar:Article|Article]] +[[Bar:Article (context)|Article]] +[[:Bar:Article (context)|Article]] +[[Article]] +[[Article (context)]] +[[Bar:X (Y) Z|X (Y) Z]] +[[:Bar:X (Y) Z|X (Y) Z]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with interwiki prefix +!! options +pst +!! input +[[interwiki:Article|]] +[[:interwiki:Article|]] +[[interwiki:Bar:Article|]] +[[:interwiki:Bar:Article|]] +!! result +[[interwiki:Article|Article]] +[[:interwiki:Article|Article]] +[[interwiki:Bar:Article|Bar:Article]] +[[:interwiki:Bar:Article|Bar:Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with parens in title +!! options +pst title=[[Somearticle (context)]] +!! input +[[|Article]] +!! result +[[Article (context)|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with comma in title +!! options +pst title=[[Someplace, Somewhere]] +!! input +[[|Otherplace]] +[[Otherplace, Elsewhere|]] +[[Otherplace, Elsewhere, Anywhere|]] +!! result +[[Otherplace, Somewhere|Otherplace]] +[[Otherplace, Elsewhere|Otherplace]] +[[Otherplace, Elsewhere, Anywhere|Otherplace]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with parens and comma +!! options +pst title=[[Someplace (IGNORED), Somewhere]] +!! input +[[|Otherplace]] +[[Otherplace (place), Elsewhere|]] +!! result +[[Otherplace, Somewhere|Otherplace]] +[[Otherplace (place), Elsewhere|Otherplace]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with comma and parens +!! options +pst title=[[Who, me? (context)]] +!! input +[[|Yes, you.]] +[[Me, Myself, and I (1937 song)|]] +!! result +[[Yes, you. (context)|Yes, you.]] +[[Me, Myself, and I (1937 song)|Me, Myself, and I]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with namespace +!! options +pst title=[[Ns:Somearticle]] +!! input +[[|Article]] +!! result +[[Ns:Article|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with namespace and parens +!! options +pst title=[[Ns:Somearticle (context)]] +!! input +[[|Article]] +!! result +[[Ns:Article (context)|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with namespace and comma +!! options +pst title=[[Ns:Somearticle, Context, Whatever]] +!! input +[[|Article]] +!! result +[[Ns:Article, Context, Whatever|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with namespace, comma and parens +!! options +pst title=[[Ns:Somearticle, Context (context)]] +!! input +[[|Article]] +!! result +[[Ns:Article (context)|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with namespace, parens and comma +!! options +pst title=[[Ns:Somearticle (IGNORED), Context]] +!! input +[[|Article]] +!! result +[[Ns:Article, Context|Article]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with full-width parens and no space (Japanese and Chinese style, bug 30149) +!! options +pst +!! input +[[Article(context)|]] +[[Bar:Article(context)|]] +[[:Bar:Article(context)|]] +[[|Article(context)]] +[[Bar:X(Y)Z|]] +[[:Bar:X(Y)Z|]] +!! result +[[Article(context)|Article]] +[[Bar:Article(context)|Article]] +[[:Bar:Article(context)|Article]] +[[Article(context)]] +[[Bar:X(Y)Z|X(Y)Z]] +[[:Bar:X(Y)Z|X(Y)Z]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with full-width parens and space (Japanese and Chinese style, bug 30149) +!! options +pst +!! input +[[Article (context)|]] +[[Bar:Article (context)|]] +[[:Bar:Article (context)|]] +[[|Article (context)]] +[[Bar:X (Y) Z|]] +[[:Bar:X (Y) Z|]] +!! result +[[Article (context)|Article]] +[[Bar:Article (context)|Article]] +[[:Bar:Article (context)|Article]] +[[Article (context)]] +[[Bar:X (Y) Z|X (Y) Z]] +[[:Bar:X (Y) Z|X (Y) Z]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with parens and no space (Korean style, bug 30149) +!! options +pst +!! input +[[Article(context)|]] +[[Bar:Article(context)|]] +[[:Bar:Article(context)|]] +[[|Article(context)]] +[[Bar:X(Y)Z|]] +[[:Bar:X(Y)Z|]] +!! result +[[Article(context)|Article]] +[[Bar:Article(context)|Article]] +[[:Bar:Article(context)|Article]] +[[Article(context)]] +[[Bar:X(Y)Z|X(Y)Z]] +[[:Bar:X(Y)Z|X(Y)Z]] +!! end + +!! test +pre-save transform: context links ("pipe trick") with commas (bug 21660) +!! options +pst +!! input +[[Article (context), context|]] +[[Article (context),context|]] +[[Bar:Article (context), context|]] +[[Bar:Article (context),context|]] +[[:Bar:Article (context), context|]] +[[:Bar:Article (context),context|]] +!! result +[[Article (context), context|Article]] +[[Article (context),context|Article]] +[[Bar:Article (context), context|Article]] +[[Bar:Article (context),context|Article]] +[[:Bar:Article (context), context|Article]] +[[:Bar:Article (context),context|Article]] +!! end + +!! test +pre-save transform: trim trailing empty lines +!! options +pst +!! input +Empty lines are trimmed + + + + +!! result +Empty lines are trimmed +!! end + +!! test +pre-save transform: Signature expansion +!! options +pst +!! input +* ~~~ +* <noinclude>~~~</noinclude> +* <includeonly>~~~</includeonly> +* <onlyinclude>~~~</onlyinclude> +!! result +* [[Special:Contributions/127.0.0.1|127.0.0.1]] +* <noinclude>[[Special:Contributions/127.0.0.1|127.0.0.1]]</noinclude> +* <includeonly>[[Special:Contributions/127.0.0.1|127.0.0.1]]</includeonly> +* <onlyinclude>[[Special:Contributions/127.0.0.1|127.0.0.1]]</onlyinclude> +!! end + + +!! test +pre-save transform: Signature expansion in nowiki tags (bug 93) +!! options +pst disabled +!! input +Shall not expand: + +<nowiki>~~~~</nowiki> + +<includeonly><nowiki>~~~~</nowiki></includeonly> + +<noinclude><nowiki>~~~~</nowiki></noinclude> + +<onlyinclude><nowiki>~~~~</nowiki></onlyinclude> + +{{subst:Foo}} shall be converted to FOO + +As well as inside noinclude/onlyinclude +<noinclude>{{subst:Foo}}</noinclude> +<onlyinclude>{{subst:Foo}}</onlyinclude> + +But not inside includeonly +<includeonly>{{subst:Foo}}</includeonly> +!! result +Shall not expand: + +<nowiki>~~~~</nowiki> + +<includeonly><nowiki>~~~~</nowiki></includeonly> + +<noinclude><nowiki>~~~~</nowiki></noinclude> + +<onlyinclude><nowiki>~~~~</nowiki></onlyinclude> + +FOO shall be converted to FOO + +As well as inside noinclude/onlyinclude +<noinclude>FOO</noinclude> +<onlyinclude>FOO</onlyinclude> + +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 +### +!! test +message transform: magic variables +!! options +msg +!! input +{{SITENAME}} +!! result +MediaWiki +!! end + +!! test +message transform: should not transform wiki markup +!! options +msg +!! input +''test'' +!! result +''test'' +!! end + +!! test +message transform: <noinclude> in transcluded template (bug 4926) +!! options +msg +!! input +{{Includes}} +!! result +Foobar +!! end + +!! test +message transform: <onlyinclude> in transcluded template (bug 4926) +!! options +msg +!! input +{{Includes2}} +!! result +Foo +!! end + +!! test +{{#special:}} page name, known +!! options +msg +!! input +{{#special:Recentchanges}} +!! result +Special:RecentChanges +!! end + +!! test +{{#special:}} page name with subpage, known +!! options +msg +!! input +{{#special:Recentchanges/param}} +!! result +Special:RecentChanges/param +!! end + +!! test +{{#special:}} page name, unknown +!! options +msg +!! input +{{#special:foobar nonexistent}} +!! result +Special:Foobar nonexistent +!! end + +!! test +{{#speciale:}} page name, known +!! options +msg +!! input +{{#speciale:Recentchanges}} +!! result +Special:RecentChanges +!! end + +!! test +{{#speciale:}} page name with subpage, known +!! options +msg +!! input +{{#speciale:Recentchanges/param}} +!! result +Special:RecentChanges/param +!! end + +!! test +{{#speciale:}} page name, unknown +!! options +msg +!! input +{{#speciale:foobar nonexistent}} +!! result +Special:Foobar_nonexistent +!! end + +### +### Images +### +### For Parsoid-specific tests, see +#### http://www.mediawiki.org/wiki/Parsoid/MediaWiki_DOM_spec#Images + +!! test +Simple image (php) +!! options +php +!! input +[[Image:foobar.jpg]] +!! result +<p><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> +</p> +!! end + +!! test +Simple image (parsoid) +!! options +parsoid=wt2html +!! input +[[Image: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 +Simple image (using File: namespace, now canonical) (php) +!! options +php +!! input +[[File:foobar.jpg]] +!! result +<p><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> +</p> +!! end + +!! test +Simple image (using File: namespace, now canonical) (parsoid) +!! options +parsoid +!! input +[[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 (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 +[[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 attributes from template (parsoid) +!! options +parsoid +!! input +[[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> +123<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>456 +123<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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></div></div></div>456 + +!! end + +!! test +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 +[[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 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 +[[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> +<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> + +!! end + +!! test +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 +[[File:Foobar.jpg|link=Main Page]] +!! result +<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, 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 +[[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 +[[Image:foobar.jpg|link=http://example.com/]] +!! config +wgExternalLinkTarget='foobar' +!! result +<p><a href="http://example.com/" target="foobar" rel="nofollow"><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, wgNoFollowLinks set to false +!! input +[[Image:foobar.jpg|link=http://example.com/]] +!! config +wgNoFollowLinks=false +!! result +<p><a href="http://example.com/"><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, wgNoFollowDomainExceptions +!! input +[[Image:foobar.jpg|link=http://example.com/]] +!! config +wgNoFollowDomainExceptions='example.com' +!! result +<p><a href="http://example.com/"><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, wgExternalLinkTarget, unnamed parameter +!! input +[[Image:foobar.jpg|link=http://example.com/|Title]] +!! config +wgExternalLinkTarget='foobar' +!! result +<p><a href="http://example.com/" title="Title" target="foobar" rel="nofollow"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Image with empty link parameter (php) +!! options +php +!! input +[[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 empty link parameter (parsoid) +!! options +parsoid +!! input +[[File:Foobar.jpg|link=]] +!! result +<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 (wiki target) and unnamed parameter (parsoid) +!! options +parsoid +!! input +[[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 +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="http://example.com/"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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 +!! 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]]]] +!! result +<div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a> <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div> + +!! end + +!! test +Image with frame and link and explicit alt +!! input +[[Image:Foobar.jpg|frame|left|This is a test image [[Main Page]]|alt=Altitude]] +!! result +<div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Altitude" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a> <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div> + +!! end + +!! test +Image with wiki markup in implicit alt +!! input +[[Image:Foobar.jpg|testing '''bold''' in alt]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="testing bold in alt"><img alt="testing bold in alt" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Image with wiki markup in explicit alt +!! input +[[Image:Foobar.jpg|alt=testing '''bold''' in alt]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="testing bold in alt" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Link to image page- image page normally doesn't exists, hence edit link +Add test with existing image page +#<p><a href="/wiki/File:Test" title="Image:Test">Image:test</a> +!! input +[[:Image:test]] +!! result +<p><a href="/index.php?title=File:Test&action=edit&redlink=1" class="new" title="File:Test (page does not exist)">Image:test</a> +</p> +!! end + +!! test +bug 18784 Link to non-existent image page with caption should use caption as link text +!! input +[[:Image:test|caption]] +!! result +<p><a href="/index.php?title=File:Test&action=edit&redlink=1" class="new" title="File:Test (page does not exist)">caption</a> +</p> +!! end + +!! test +Frameless image caption with a free URL +!! input +[[Image:foobar.jpg|http://example.com]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="http://example.com"><img alt="http://example.com" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Thumbnail image caption with a free URL +!! input +[[Image:foobar.jpg|thumb|http://example.com]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div> + +!! end + +!! test +Thumbnail image caption with a free URL and explicit alt +!! input +[[Image:foobar.jpg|thumb|http://example.com|alt=Alteration]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Alteration" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div> + +!! 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]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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><a href="/wiki/Special:BookSources/1235467890" class="internal mw-magiclink-isbn">ISBN 1235467890</a></div></div></div> + +!! end + +!! test +BUG 1887: A RFC with a thumbnail +!! input +[[Image:foobar.jpg|thumb|This is RFC 12354]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>This is <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div> + +!! end + +!! test +BUG 1887: A mailto link with a thumbnail +!! input +[[Image:foobar.jpg|thumb|Please mailto:nobody@example.com]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>Please <a rel="nofollow" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></div></div></div> + +!! end + +# Pending resolution to bug 368 +!! test +BUG 648: Frameless image caption with a link +!! input +[[Image:foobar.jpg|text with a [[link]] in it]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a link in it"><img alt="text with a link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +BUG 648: Frameless image caption with a link (suffix) +!! input +[[Image:foobar.jpg|text with a [[link]]foo in it]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a linkfoo in it"><img alt="text with a linkfoo in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +BUG 648: Frameless image caption with an interwiki link +!! input +[[Image:foobar.jpg|text with a [[MeatBall:Link]] in it]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a MeatBall:Link in it"><img alt="text with a MeatBall:Link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +BUG 648: Frameless image caption with a piped interwiki link +!! input +[[Image:foobar.jpg|text with a [[MeatBall:Link|link]] in it]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="text with a link in it"><img alt="text with a link in it" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Escape HTML special chars in image alt text +!! input +[[Image:foobar.jpg|& < > "]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="& < > ""><img alt="& < > "" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +BUG 499: Alt text should have Ӓ, not &1234; +!! input +[[Image:foobar.jpg|♀]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="♀"><img alt="♀" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!! end + +!! test +Broken image caption with link +!! input +[[Image:Foobar.jpg|thumb|This is a broken caption. But [[Main Page|this]] is just an ordinary link. +!! result +<p>[[Image:Foobar.jpg|thumb|This is a broken caption. But <a href="/wiki/Main_Page" title="Main Page">this</a> is just an ordinary link. +</p> +!! end + +!! test +Image caption containing another image +!! input +[[Image:Foobar.jpg|thumb|This is a caption with another [[Image:icon.png|image]] inside it!]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>This is a caption with another <a href="/index.php?title=Special:Upload&wpDestFile=Icon.png" class="new" title="File:Icon.png">image</a> inside it!</div></div></div> + +!! end + +!! test +Image caption containing a newline +!! input +[[Image:Foobar.jpg|This +*is some text]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="This *is some text"><img alt="This *is some text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a> +</p> +!!end + +!!test +Parsoid: Image caption containing leading space +(The leading space should not trigger nowiki escaping in wt2wt mode) +!! input +[[Image:Foobar.jpg|thumb| bar]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>bar</div></div></div> + +!!end + +!! test +Bug 3090: External links other than http: in image captions +!! input +[[Image:Foobar.jpg|thumb|200px|This caption has [irc://example.net irc] and [https://example.com Secure] ext links in it.]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" 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 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>This caption has <a rel="nofollow" class="external text" href="irc://example.net">irc</a> and <a rel="nofollow" class="external text" href="https://example.com">Secure</a> ext links in it.</div></div></div> + +!! end + +!! test +Custom class +!! input +[[Image:foobar.jpg|a|class=b]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="a"><img alt="a" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="b" /></a> +</p> +!! end + +!! test +Localized image handling (1). +!! options +language=es +!! input +[[Archivo:Foobar.jpg|izquierda|enlace=foo|caption]] +!! result +<div class="floatleft"><a href="/wiki/Foo" title="caption"><img alt="caption" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div> + +!! end + +!! test +Localized image handling (2). +!! options +language=es +!! input +[[Archivo:Foobar.jpg|miniatura|izquierda|enlace=foo|caption]] +!! result +<div class="thumb tleft"><div class="thumbinner" style="width:182px;"><a href="/wiki/Foo" title="Foo"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/Archivo:Foobar.jpg" class="internal" title="Aumentar"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>caption</div></div></div> + +!! end + +!! test +"border", "frameless" and "class" attributes on an image. +!! input +[[File:Foobar.jpg|frameless|border|class=extra|caption]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image" title="caption"><img alt="caption" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="extra thumbborder" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> +</p> +!! end + +!! article +File:Barfoo.jpg +!! text +#REDIRECT [[File:Barfoo.jpg]] +!! endarticle + +!! test +Redirected image +!! input +[[Image:Barfoo.jpg]] +!! result +<p><a href="/wiki/File:Barfoo.jpg" title="File:Barfoo.jpg">File:Barfoo.jpg</a> +</p> +!! end + +!! test +Missing image with uploads disabled +!! options +wgEnableUploads=0 +!! input +[[Image:Foobaz.jpg]] +!! result +<p><a href="/wiki/File:Foobaz.jpg" title="File:Foobaz.jpg">File:Foobaz.jpg</a> +</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 +### +!! article +Subpage test/subpage +!! text +foo +!! endarticle + +!! test +Subpage link +!! options +subpage title=[[Subpage test]] +!! input +[[/subpage]] +!! result +<p><a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">/subpage</a> +</p> +!! end + +!! test +Subpage noslash link +!! options +subpage title=[[Subpage test]] +!!input +[[/subpage/]] +!! result +<p><a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">subpage</a> +</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 +[[/subpage]] +!! result +<p><a href="/index.php?title=/subpage&action=edit&redlink=1" class="new" title="/subpage (page does not exist)">/subpage</a> +</p> +!! end + +!! test +BUG 561: {{/Subpage}} +!! options +subpage title=[[Page]] +!! input +{{/Subpage}} +!! result +<p><a href="/index.php?title=Page/Subpage&action=edit&redlink=1" class="new" title="Page/Subpage (page does not exist)">Page/Subpage</a> +</p> +!! end + +### +### Categories +### +!! article +Category:MediaWiki User's Guide +!! text +blah +!! endarticle + +!! test +Link to category +!! input +[[:Category:MediaWiki User's Guide]] +!! result +<p><a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">Category:MediaWiki User's Guide</a> +</p> +!! end + +!! test +Simple category +!! options +cat +!! input +[[Category:MediaWiki User's Guide]] +!! result +<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a> +!! end + +!! test +PAGESINCATEGORY invalid title fatal (r33546 fix) +!! input +{{PAGESINCATEGORY:<bogus>}} +!! result +<p>0 +</p> +!! end + +!! test +Category with different sort key +!! options +cat +!! input +[[Category:MediaWiki User's Guide|Foo]] +!! result +<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a> +!! end + +!! test +Category with identical sort key +!! options +cat +!! input +[[Category:MediaWiki User's Guide|MediaWiki User's Guide]] +!! result +<a href="/wiki/Category:MediaWiki_User%27s_Guide" title="Category:MediaWiki User's Guide">MediaWiki User's Guide</a> +!! end + +!! test +Category with empty sort key +!! options +cat +pst +!! input +[[Category:MediaWiki User's Guide|]] +!! result +[[Category:MediaWiki User's Guide|MediaWiki User's Guide]] +!! end + +!! test +Category with empty sort key and parentheses +!! options +cat +pst +!! input +[[Category:Foo (bar)|]] +!! result +[[Category:Foo (bar)|Foo]] +!! end + +!! test +Category with link tail +!! options +cat +pst +!! input +123[[Category:Foo]]456 +!! result +123[[Category:Foo]]456 +!! end + +!! test +Category with template +!! options +cat +pst +!! input +[[Category:{{echo|Foo}}]] +!! result +[[Category:{{echo|Foo}}]] +!! end + +!! test +Category with template in sort key +!! options +cat +pst +!! input +[[Category:Foo|{{echo|Bar}}]] +!! result +[[Category:Foo|{{echo|Bar}}]] +!! end + +!! test +Category with template in sort key and title +!! options +cat +pst +!! input +[[Category:{{echo|Foo}}|{{echo|Bar}}]] +!! result +[[Category:{{echo|Foo}}|{{echo|Bar}}]] +!! end + +!! test +Category / paragraph interactions +!! input +Foo [[Category:Baz]] Bar + +Foo [[Category:Baz]] +Bar + +Foo +[[Category:Baz]] +Bar + +Foo +[[Category:Baz]] Bar + +Foo +[[Category:Baz]] + [[Category:Baz]] +[[Category:Baz]] +Bar + +[[Category:Baz]] + [[Category:Baz]] +[[Category:Baz]] + +[[Category:Baz]] + {{echo|[[Category:Baz]]}} +[[Category:Baz]] +!! result +<p>Foo Bar +</p><p>Foo +Bar +</p><p>Foo +Bar +</p><p>Foo Bar +</p><p>Foo +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 +### +!! test +Inter-language links +!! options +ill +!! input +[[es:Alimento]] +[[fr:Nourriture]] +[[zh:食品]] +!! result +es:Alimento fr:Nourriture zh:食品 +!! end + +!! test +Duplicate interlanguage links (bug 24502) +!! options +ill +!! input +[[es:1]] +[[es:2]] +[[fr:1]] +[[fr:2]] +!! result +es:1 fr:1 +!! end + +### +### Sections +### +!! test +Basic section headings +!! input +== Headline 1 == +Some text + +==Headline 2== +More +===Smaller headline=== +Blah blah +!! result +<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="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="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 + +!! test +Section headings with TOC +!! input +== Headline 1 == +=== Subheadline 1 === +===== Skipping a level ===== +====== Skipping a level ====== + +== Headline 2 == +Some text +===Another headline=== +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#Subheadline_1"><span class="tocnumber">1.1</span> <span class="toctext">Subheadline 1</span></a> +<ul> +<li class="toclevel-3 tocsection-3"><a href="#Skipping_a_level"><span class="tocnumber">1.1.1</span> <span class="toctext">Skipping a level</span></a> +<ul> +<li class="toclevel-4 tocsection-4"><a href="#Skipping_a_level_2"><span class="tocnumber">1.1.1.1</span> <span class="toctext">Skipping a level</span></a></li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +<li class="toclevel-1 tocsection-5"><a href="#Headline_2"><span class="tocnumber">2</span> <span class="toctext">Headline 2</span></a> +<ul> +<li class="toclevel-2 tocsection-6"><a href="#Another_headline"><span class="tocnumber">2.1</span> <span class="toctext">Another headline</span></a></li> +</ul> +</li> +</ul> +</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="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 + +# perl -e 'print "="x$_," Level $_ heading","="x$_,"\n" for 1..10' +!! test +Handling of sections up to level 6 and beyond +!! input += Level 1 Heading= +== Level 2 Heading== +=== Level 3 Heading=== +==== Level 4 Heading==== +===== Level 5 Heading===== +====== Level 6 Heading====== +======= Level 7 Heading======= +======== Level 8 Heading======== +========= Level 9 Heading========= +========== Level 10 Heading========== +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#Level_2_Heading"><span class="tocnumber">1.1</span> <span class="toctext">Level 2 Heading</span></a> +<ul> +<li class="toclevel-3 tocsection-3"><a href="#Level_3_Heading"><span class="tocnumber">1.1.1</span> <span class="toctext">Level 3 Heading</span></a> +<ul> +<li class="toclevel-4 tocsection-4"><a href="#Level_4_Heading"><span class="tocnumber">1.1.1.1</span> <span class="toctext">Level 4 Heading</span></a> +<ul> +<li class="toclevel-5 tocsection-5"><a href="#Level_5_Heading"><span class="tocnumber">1.1.1.1.1</span> <span class="toctext">Level 5 Heading</span></a> +<ul> +<li class="toclevel-6 tocsection-6"><a href="#Level_6_Heading"><span class="tocnumber">1.1.1.1.1.1</span> <span class="toctext">Level 6 Heading</span></a></li> +<li class="toclevel-6 tocsection-7"><a href="#.3D_Level_7_Heading.3D"><span class="tocnumber">1.1.1.1.1.2</span> <span class="toctext">= Level 7 Heading=</span></a></li> +<li class="toclevel-6 tocsection-8"><a href="#.3D.3D_Level_8_Heading.3D.3D"><span class="tocnumber">1.1.1.1.1.3</span> <span class="toctext">== Level 8 Heading==</span></a></li> +<li class="toclevel-6 tocsection-9"><a href="#.3D.3D.3D_Level_9_Heading.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.4</span> <span class="toctext">=== Level 9 Heading===</span></a></li> +<li class="toclevel-6 tocsection-10"><a href="#.3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D"><span class="tocnumber">1.1.1.1.1.5</span> <span class="toctext">==== Level 10 Heading====</span></a></li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</li> +</ul> +</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 + +!! test +TOC regression (bug 9764) +!! input +== title 1 == +=== title 1.1 === +==== title 1.1.1 ==== +=== title 1.2 === +== title 2 == +=== title 2.1 === +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#title_1.1"><span class="tocnumber">1.1</span> <span class="toctext">title 1.1</span></a> +<ul> +<li class="toclevel-3 tocsection-3"><a href="#title_1.1.1"><span class="tocnumber">1.1.1</span> <span class="toctext">title 1.1.1</span></a></li> +</ul> +</li> +<li class="toclevel-2 tocsection-4"><a href="#title_1.2"><span class="tocnumber">1.2</span> <span class="toctext">title 1.2</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-5"><a href="#title_2"><span class="tocnumber">2</span> <span class="toctext">title 2</span></a> +<ul> +<li class="toclevel-2 tocsection-6"><a href="#title_2.1"><span class="tocnumber">2.1</span> <span class="toctext">title 2.1</span></a></li> +</ul> +</li> +</ul> +</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 + +!! test +TOC with wgMaxTocLevel=3 (bug 6204) +!! options +wgMaxTocLevel=3 +!! input +== title 1 == +=== title 1.1 === +==== title 1.1.1 ==== +=== title 1.2 === +== title 2 == +=== title 2.1 === +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#title_1.1"><span class="tocnumber">1.1</span> <span class="toctext">title 1.1</span></a></li> +<li class="toclevel-2 tocsection-4"><a href="#title_1.2"><span class="tocnumber">1.2</span> <span class="toctext">title 1.2</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-5"><a href="#title_2"><span class="tocnumber">2</span> <span class="toctext">title 2</span></a> +<ul> +<li class="toclevel-2 tocsection-6"><a href="#title_2.1"><span class="tocnumber">2.1</span> <span class="toctext">title 2.1</span></a></li> +</ul> +</li> +</ul> +</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 + +!! test +TOC with wgMaxTocLevel=3 and two level four headings (bug 6204) +!! options +wgMaxTocLevel=3 +!! input +==Section 1== +===Section 1.1=== +====Section 1.1.1==== +====Section 1.1.1.1==== +==Section 2== +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#Section_1.1"><span class="tocnumber">1.1</span> <span class="toctext">Section 1.1</span></a></li> +</ul> +</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> +</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 + + +!! test +Resolving duplicate section names +!! input +== Foo bar == +== Foo bar == +!! result +<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 + +!! test +Resolving duplicate section names with differing case (bug 10721) +!! input +== Foo bar == +== Foo Bar == +!! result +<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 + +!! article +Template:sections +!! text +===Section 1=== +==Section 2== +!! endarticle + +!! test +Template with sections, __NOTOC__ +!! input +__NOTOC__ +==Section 0== +{{sections}} +==Section 4== +!! result +<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 + +!! test +__NOEDITSECTION__ keyword +!! input +__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> + +!! end + +!! test +Link inside a section heading +!! input +==Section with a [[Main Page|link]] in it== +!! result +<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 + +!! test +TOC regression (bug 12077) +!! input +__TOC__ +== title 1 == +=== title 1.1 === +== title 2 == +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#title_1.1"><span class="tocnumber">1.1</span> <span class="toctext">title 1.1</span></a></li> +</ul> +</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> +</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 + +!! test +BUG 1219 URL next to image (good) +!! input +http://example.com [[Image:foobar.jpg]] +!! result +<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a> <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> +</p> +!!end + +!! test +Short headings with trailing space should match behavior of Parser::doHeadings (bug 19910) +!! input +=== +The line above must have a trailing space! +=== <!-- +--> <!-- --> +But just in case it doesn't... +!! result +<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="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 + +!! test +Header with special characters (bug 25462) +!! input +The tooltips shall not show entities to the user (ie. be double escaped) + +== text > text == +section 1 + +== text < text == +section 2 + +== text & text == +section 3 + +== text ' text == +section 4 + +== text " text == +section 5 +!! result +<p>The tooltips shall not show entities to the user (ie. be double escaped) +</p> +<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> +<li class="toclevel-1 tocsection-3"><a href="#text_.26_text"><span class="tocnumber">3</span> <span class="toctext">text & text</span></a></li> +<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> +</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="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="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="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="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 + +!! test +Headers with excess '=' characters +(Are similar tests necessary beyond the 1st level?) +!! input +=foo== +==foo= +=''italic'' heading== +==''italic'' heading= +!! result +<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> +</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 + +!! test +BUG 1219 URL next to image (broken) +!! input +http://example.com[[Image:foobar.jpg]] +!! result +<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a><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> +</p> +!!end + +!! test +Bug 1186 news: in the middle of text +!! input +http://en.wikinews.org/wiki/Wikinews:Workplace +!! result +<p><a rel="nofollow" class="external free" href="http://en.wikinews.org/wiki/Wikinews:Workplace">http://en.wikinews.org/wiki/Wikinews:Workplace</a> +</p> +!!end + + +!! test +Namespaced link must have a title +!! input +[[Project:]] +!! result +<p>[[Project:]] +</p> +!!end + +!! test +Namespaced link must have a title (bad fragment version) +!! input +[[Project:#fragment]] +!! result +<p>[[Project:#fragment]] +</p> +!!end + + +### +### HTML tags and HTML attributes +### + +!! test +div with no attributes +!! input +<div>HTML rocks</div> +!! result +<div>HTML rocks</div> + +!! end + +!! test +div with double-quoted attribute +!! input +<div id="rock">HTML rocks</div> +!! result +<div id="rock">HTML rocks</div> + +!! end + +!! test +div with single-quoted attribute +!! input +<div id='rock'>HTML rocks</div> +!! result +<div id="rock">HTML rocks</div> + +!! end + +!! test +div with unquoted attribute +!! input +<div id=rock>HTML rocks</div> +!! result +<div id="rock">HTML rocks</div> + +!! end + +!! test +div with illegal double attributes +!! input +<div id="a" id="b">HTML rocks</div> +!! result +<div id="b">HTML rocks</div> + +!!end + +# FIXME: produce empty string instead of "class" in the PHP parser, following +# the HTML5 spec. +!! test +div with empty attribute value, space before equals +!! options +parsoid +!! input +<div class =>HTML rocks</div> +!! result +<div class="">HTML rocks</div> + +!! end + +# The PHP parser escapes the opening brace to { for some reason, so +# disabled this test for it. +!! test +div with braces in attribute value +!! options +parsoid +!! input +<div title="{}">Foo</div> +!! result +<div title="{}">Foo</div> +!! end + +# This it very inconsistent in the PHP parser: it returns +# class="class" if there is a space between the name and the equal sign (see +# 'div with empty attribute value, space before equals'), but strips the +# attribute completely if the space is missing. We hope that not much content +# depends on this, so are implementing the behavior below in Parsoid for +# consistencies' sake. Disabled for the PHP parser. +# FIXME: fix this behavior in the PHP parser? +!! test +div with empty attribute value, no space before equals +!! options +parsoid +!! input +<div class=>HTML rocks</div> +!! result +<div class="">HTML rocks</div> + +!! end + +!! test +HTML multiple attributes correction +!! input +<p class="error" class="awesome">Awesome!</p> +!! result +<p class="awesome">Awesome!</p> + +!!end + +!! test +Table multiple attributes correction +!! input +{| +!+ class="error" class="awesome"| status +|} +!! result +<table> +<tr> +<th class="awesome"> status +</th></tr></table> + +!!end + +!! test +DIV IN UPPERCASE +!! input +<DIV ID="x">HTML ROCKS</DIV> +!! result +<div id="x">HTML ROCKS</div> + +!!end + +!! test +Non-ASCII pseudo-tags are rendered as text +!! input +<khyô> +!! result +<p><khyô> +</p> +!! end + +!! test +Pseudo-tag with URL 'name' renders as url link +!! input +<http://example.com/> +!! result +<p><<a rel="nofollow" class="external free" href="http://example.com/">http://example.com/</a>> +</p> +!! end + +!! test +text with amp in the middle of nowhere +!! input +Remember AT&T? +!!result +<p>Remember AT&T? +</p> +!! end + +!! test +text with character entity: eacute +!! input +I always thought é was a cute letter. +!! result +<p>I always thought é was a cute letter. +</p> +!! end + +!! test +text with entity-escaped character entity-like string: eacute +!! input +I always thought &eacute; was a cute letter. +!! result +<p>I always thought &eacute; was a cute letter. +</p> +!! end + +!! test +text with undefined character entity: xacute +!! input +I always thought &xacute; was a cute letter. +!! result +<p>I always thought &xacute; was a cute letter. +</p> +!! end + + +### +### 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 +### + +!! test +Media link +!! input +[[Media:Foobar.jpg]] +!! result +<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Media:Foobar.jpg</a> +</p> +!! end + +!! test +Media link with text +!! input +[[Media:Foobar.jpg|A neat file to look at]] +!! result +<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">A neat file to look at</a> +</p> +!! end + +# FIXME: this is still bad HTML tag nesting +!! test +Media link with nasty text +fixme: doBlockLevels won't wrap this in a paragraph because it contains a div +!! input +[[Media:Foobar.jpg|Safe Link<div style=display:none>" onmouseover="alert(document.cookie)" onfoo="</div>]] +!! result +<a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link<div style="display:none">" onmouseover="alert(document.cookie)" onfoo="</div></a> + +!! end + +!! test +Media link to nonexistent file (bug 1702) +!! input +[[Media:No such.jpg]] +!! result +<p><a href="/index.php?title=Special:Upload&wpDestFile=No_such.jpg" class="new" title="No such.jpg">Media:No such.jpg</a> +</p> +!! end + +!! test +Image link to nonexistent file (bug 1850 - good) +!! input +[[Image:No such.jpg]] +!! result +<p><a href="/index.php?title=Special:Upload&wpDestFile=No_such.jpg" class="new" title="File:No such.jpg">File:No such.jpg</a> +</p> +!! end + +!! test +:Image link to nonexistent file (bug 1850 - bad) +!! input +[[:Image:No such.jpg]] +!! result +<p><a href="/index.php?title=File:No_such.jpg&action=edit&redlink=1" class="new" title="File:No such.jpg (page does not exist)">Image:No such.jpg</a> +</p> +!! end + + + +!! test +Character reference normalization in link text (bug 1938) +!! input +[[Main Page|this&that]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">this&that</a> +</p> +!!end + +!! article +אַ +!! text +Test for unicode normalization + +The page's name is U+05d0 U+05b7, with non-canonical form U+FB2E +!! endarticle + +!! test +(bug 19451) Links should refer to the normalized form. +!! input +[[אַ]] +[[אַ]] +[[אַ]] +[[אַ]] +[[אַ]] +!! result +<p><a href="/wiki/%D7%90%D6%B7" title="אַ">אַ</a> +<a href="/wiki/%D7%90%D6%B7" title="אַ">אַ</a> +<a href="/wiki/%D7%90%D6%B7" title="אַ">אַ</a> +<a href="/wiki/%D7%90%D6%B7" title="אַ">אַ</a> +<a href="/wiki/%D7%90%D6%B7" title="אַ">אַ</a> +</p> +!! end + +!! test +Empty attribute crash test (bug 2067) +!! input +<font color="">foo</font> +!! result +<p><font color="">foo</font> +</p> +!! end + +!! test +Empty attribute crash test single-quotes (bug 2067) +!! input +<font color=''>foo</font> +!! result +<p><font color="">foo</font> +</p> +!! end + +!! test +Attribute test: equals, then nothing +!! input +<font color=>foo</font> +!! result +<p><font>foo</font> +</p> +!! end + +!! test +Attribute test: unquoted value +!! input +<font color=x>foo</font> +!! result +<p><font color="x">foo</font> +</p> +!! end + +!! test +Attribute test: unquoted but illegal value (hash) +!! input +<font color=#x>foo</font> +!! result +<p><font color="#x">foo</font> +</p> +!! end + +!! test +Attribute test: no value +!! input +<font color>foo</font> +!! result +<p><font color="color">foo</font> +</p> +!! end + +!! test +Bug 2095: link with three closing brackets +!! input +[[Main Page]]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>] +</p> +!! end + +!! test +Bug 2095: link with pipe and three closing brackets +!! input +[[Main Page|link]]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">link</a>] +</p> +!! end + +!! test +Bug 2095: link with pipe and three closing brackets, version 2 +!! input +[[Main Page|[http://example.com/]]] +!! result +<p><a href="/wiki/Main_Page" title="Main Page">[http://example.com/]</a> +</p> +!! end + + +### +### Safety +### + +!! article +Template:Dangerous attribute +!! text +" onmouseover="alert(document.cookie) +!! endarticle + +!! article +Template:Dangerous style attribute +!! text +border-size: expression(alert(document.cookie)) +!! endarticle + +!! article +Template:Div style +!! text +<div style="float: right; {{{1}}}">Magic div</div> +!! endarticle + +!! test +Bug 2304: HTML attribute safety (safe template; regression bug 2309) +!! input +<div title="{{test}}"></div> +!! result +<div title="This is a test template"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (dangerous template; 2309) +!! input +<div title="{{dangerous attribute}}"></div> +!! result +<div title=""></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (dangerous style template; 2309) +!! input +<div style="{{dangerous style attribute}}"></div> +!! result +<div style="/* insecure input */"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (safe parameter; 2309) +!! input +{{div style|width: 200px}} +!! result +<div style="float: right; width: 200px">Magic div</div> + +!! end + +!! test +Bug 2304: HTML attribute safety (unsafe parameter; 2309) +!! input +{{div style|width: expression(alert(document.cookie))}} +!! result +<div style="/* insecure input */">Magic div</div> + +!! end + +!! test +Bug 2304: HTML attribute safety (unsafe breakout parameter; 2309) +!! input +{{div style|"><script>alert(document.cookie)</script>}} +!! result +<div style="float: right;"><script>alert(document.cookie)</script>">Magic div</div> + +!! end + +!! test +Bug 2304: HTML attribute safety (unsafe breakout parameter 2; 2309) +!! input +{{div style|" ><script>alert(document.cookie)</script>}} +!! result +<div style="float: right;"><script>alert(document.cookie)</script>">Magic div</div> + +!! end + +!! test +Bug 2304: HTML attribute safety (link) +!! input +<div title="[[Main Page]]"></div> +!! result +<div title="[[Main Page]]"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (italics) +!! input +<div title="''foobar''"></div> +!! result +<div title="''foobar''"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (bold) +!! input +<div title="'''foobar'''"></div> +!! result +<div title="'''foobar'''"></div> + +!! end + + +!! test +Bug 2304: HTML attribute safety (ISBN) +!! input +<div title="ISBN 1234567890"></div> +!! result +<div title="ISBN 1234567890"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (RFC) +!! input +<div title="RFC 1234"></div> +!! result +<div title="RFC 1234"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (PMID) +!! input +<div title="PMID 1234567890"></div> +!! result +<div title="PMID 1234567890"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (web link) +!! input +<div title="http://example.com/"></div> +!! result +<div title="http://example.com/"></div> + +!! end + +!! test +Bug 2304: HTML attribute safety (named web link) +!! input +<div title="[http://example.com/ link]"></div> +!! result +<div title="[http://example.com/ link]"></div> + +!! end + +!! test +Bug 3244: HTML attribute safety (extension; safe) +!! input +<div style="<nowiki>background:blue</nowiki>"></div> +!! result +<div style="background:blue"></div> + +!! end + +!! test +Bug 3244: HTML attribute safety (extension; unsafe) +!! input +<div style="<nowiki>border-left:expression(alert(document.cookie))</nowiki>"></div> +!! result +<div style="/* insecure input */"></div> + +!! end + +!! test +Opera -o-link CSS +!! input +<div +title="data:text/html,<img src=1 onerror=alert(1)>" +style="-o-link:attr(title);-o-link-source:current">X</div> +!! result +<div title="data:text/html,<img src=1 onerror=alert(1)>" style="/* insecure input */">X</div> + +!! end + +# More MSIE fun discovered by Tom Gilder + +!! test +MSIE CSS safety test: spurious slash +!! input +<div style="background-image:u\rl(javascript:alert('boo'))">evil</div> +!! result +<div style="/* insecure input */">evil</div> + +!! end + +!! test +MSIE CSS safety test: hex code +!! input +<div style="background-image:u\72l(javascript:alert('boo'))">evil</div> +!! result +<div style="/* insecure input */">evil</div> + +!! end + +!! test +MSIE CSS safety test: comment in url +!! input +<div style="background-image:u/**/rl(javascript:alert('boo'))">evil</div> +!! result +<div style="background-image:u rl(javascript:alert('boo'))">evil</div> + +!! end + +!! test +MSIE CSS safety test: comment in expression +!! input +<div style="background-image:expres/**/sion(alert('boo4'))">evil4</div> +!! result +<div style="background-image:expres sion(alert('boo4'))">evil4</div> + +!! 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 +!! input +{| +!+ style="<nowiki>color:blue</nowiki>"| status +|} +!! result +<table> +<tr> +<th style="color:blue"> status +</th></tr></table> + +!!end + +!! test +Table attribute safety +!! input +{| +!+ style="<nowiki>border-width:expression(0+alert(document.cookie))</nowiki>"| status +|} +!! result +<table> +<tr> +<th style="/* insecure input */"> status +</th></tr></table> + +!! end + +!! test +CSS line continuation 1 +!! input +<div style="background-image: u\ rl(test.jpg);"></div> +!! result +<div style="/* insecure input */"></div> + +!! end + +!! test +CSS line continuation 2 +!! input +<div style="background-image: u\ rl(test.jpg); "></div> +!! result +<div style="/* insecure input */"></div> + +!! end + +!! article +Template:Identity +!! text +{{{1}}} +!! endarticle + +!! test +Expansion of multi-line templates in attribute values (bug 6255) +!! input +<div style="background: {{identity|#00FF00}}">-</div> +!! result +<div style="background: #00FF00">-</div> + +!! end + + +!! test +Expansion of multi-line templates in attribute values (bug 6255 sanity check) +!! input +<div style="background: +#00FF00">-</div> +!! result +<div style="background: #00FF00">-</div> + +!! end + +!! test +Expansion of multi-line templates in attribute values (bug 6255 sanity check 2) +!! input +<div style="background: #00FF00">-</div> +!! result +<div style="background: #00FF00">-</div> + +!! end + +### +### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension) +### +!! test +Parser hook: empty input +!! input +<tag></tag> +!! result +<pre> +'' +array ( +) +</pre> + +!! end + +!! test +Parser hook: empty input using terminated empty elements +!! input +<tag/> +!! result +<pre> +NULL +array ( +) +</pre> + +!! end + +!! test +Parser hook: empty input using terminated empty elements (space before) +!! input +<tag /> +!! result +<pre> +NULL +array ( +) +</pre> + +!! end + +!! test +Parser hook: basic input +!! input +<tag>input</tag> +!! result +<pre> +'input' +array ( +) +</pre> + +!! end + + +!! test +Parser hook: case insensitive +!! input +<TAG>input</TAG> +!! result +<pre> +'input' +array ( +) +</pre> + +!! end + + +!! test +Parser hook: case insensitive, redux +!! input +<TaG>input</TAg> +!! result +<pre> +'input' +array ( +) +</pre> + +!! end + +!! test +Parser hook: nested tags +!! options +noxml +!! input +<tag><tag></tag></tag> +!! result +<pre> +'<tag>' +array ( +) +</pre></tag> + +!! end + +!! test +Parser hook: basic arguments +!! input +<tag width=200 height = "100" depth = '50' square></tag> +!! result +<pre> +'' +array ( + 'width' => '200', + 'height' => '100', + 'depth' => '50', + 'square' => 'square', +) +</pre> + +!! end + +!! test +Parser hook: argument containing a forward slash (bug 5344) +!! input +<tag filename='/tmp/bla'></tag> +!! result +<pre> +'' +array ( + 'filename' => '/tmp/bla', +) +</pre> + +!! end + +!! test +Parser hook: empty input using terminated empty elements (bug 2374) +!! input +<tag foo=bar/>text +!! result +<pre> +NULL +array ( + 'foo' => 'bar', +) +</pre>text + +!! end + +# </tag> should be output literally since there is no matching tag that begins it +!! test +Parser hook: basic arguments using terminated empty elements (bug 2374) +!! input +<tag width=200 height = "100" depth = '50' square/> +other stuff +</tag> +!! result +<pre> +NULL +array ( + 'width' => '200', + 'height' => '100', + 'depth' => '50', + 'square' => 'square', +) +</pre> +<p>other stuff +</tag> +</p> +!! end + +### +### (see tests/parser/parserTestsParserHook.php for the <statictag> extension) +### + +!! test +Parser hook: static parser hook not inside a comment +!! input +<statictag>hello, world</statictag> +<statictag action=flush/> +!! result +<p>hello, world +</p> +!! end + + +!! test +Parser hook: static parser hook inside a comment +!! input +<!-- <statictag>hello, world</statictag> --> +<statictag action=flush/> +!! result +<p><br /> +</p> +!! end + +# Nested template calls; this case was broken by Parser.php rev 1.506, +# since reverted. + +!! article +Template:One-parameter +!! text +(My parameter is: {{{1}}}) +!! endarticle + +!! article +Template:Map-one-parameter +!! text +{{{{{1}}}|{{{2}}}}} +!! endarticle + +!! test +Nested template calls +!! input +{{Map-one-parameter|One-parameter|param}} +!! result +<p>(My parameter is: param) +</p> +!! end + + +### +### Sanitizer +### +!! test +Sanitizer: Closing of open tags +!! input +<s></s><table></table> +!! result +<s></s><table></table> + +!! end + +!! test +Sanitizer: Closing of open but not closed tags +!! input +<s>foo +!! result +<p><s>foo</s> +</p> +!! end + +!! test +Sanitizer: Closing of closed but not open tags +!! input +</s> +!! result +<p></s> +</p> +!! end + +!! test +Sanitizer: Closing of closed but not open table tags +!! input +Table not started</td></tr></table> +!! result +<p>Table not started</td></tr></table> +</p> +!! end + +!! test +Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id="" +!! input +<span id="æ: v">byte</span>[[#æ: v|backlink]] +!! result +<p><span id=".C3.A6:_v">byte</span><a href="#.C3.A6:_v">backlink</a> +</p> +!! end + +!! test +Sanitizer: Validating the contents of the id attribute (bug 4515) +!! options +disabled +!! input +<br id=9 /> +!! result +Something, but definitely not <br id="9" />... +!! end + +!! test +Sanitizer: Validating id attribute uniqueness (bug 4515, bug 6301) +!! options +disabled +!! input +<br id="foo" /><br id="foo" /> +!! result +Something need to be done. foo-2 ? +!! end + +!! test +Sanitizer: Validating that <meta> and <link> work, but only for Microdata +!! input +<div itemscope> + <meta itemprop="hello" content="world"> + <meta http-equiv="refresh" content="5"> + <meta itemprop="hello" http-equiv="refresh" content="5"> + <link itemprop="hello" href="{{SERVER}}"> + <link rel="stylesheet" href="{{SERVER}}"> + <link rel="stylesheet" itemprop="hello" href="{{SERVER}}"> +</div> +!! result +<div itemscope="itemscope"> +<p> <meta itemprop="hello" content="world" /> + <meta http-equiv="refresh" content="5"> + <meta itemprop="hello" content="5" /> +</p> + <link itemprop="hello" href="http://example.org" /> + <link rel="stylesheet" href="<a rel="nofollow" class="external free" href="http://example.org">http://example.org</a>"> + <link itemprop="hello" href="http://example.org" /> +</div> + +!! end + +!! test +Language converter: output gets cut off unexpectedly (bug 5757) +!! options +language=zh +!! input +this bit is safe: }- + +but if we add a conversion instance: -{zh-cn:xxx;zh-tw:yyy}- + +then we get cut off here: }- + +all additional text is vanished +!! result +<p>this bit is safe: }- +</p><p>but if we add a conversion instance: xxx +</p><p>then we get cut off here: }- +</p><p>all additional text is vanished +</p> +!! end + +!! test +Self closed html pairs (bug 5487) +!! options +!! input +<center><font id="bug" />Centered text</center> +<div><font id="bug2" />In div text</div> +!! result +<center><font id="bug" />Centered text</center> +<div><font id="bug2" />In div text</div> + +!! end + +# +# +# + +!! test +Punctuation: nbsp before exclamation +!! input +C'est grave ! +!! result +<p>C'est grave ! +</p> +!! end + +!! test +Punctuation: CSS !important (bug 11874) +!! input +<div style="width:50% !important">important</div> +!! result +<div style="width:50% !important">important</div> + +!!end + +!! test +Punctuation: CSS ! important (bug 11874; with space after) +!! input +<div style="width:50% ! important">important</div> +!! result +<div style="width:50% ! important">important</div> + +!!end + + +!! test +HTML bullet list, closed tags (bug 5497) +!! input +<ul> +<li>One</li> +<li>Two</li> +</ul> +!! result +<ul> +<li>One</li> +<li>Two</li> +</ul> + +!! end + +!! test +HTML bullet list, unclosed tags (bug 5497) +!! options +disabled +!! input +<ul> +<li>One +<li>Two +</ul> +!! result +<ul> +<li>One +</li> +<li>Two +</li> +</ul> + +!! end + +!! test +HTML ordered list, closed tags (bug 5497) +!! input +<ol> +<li>One</li> +<li>Two</li> +</ol> +!! result +<ol> +<li>One</li> +<li>Two</li> +</ol> + +!! end + +!! test +HTML ordered list, unclosed tags (bug 5497) +!! options +disabled +!! input +<ol> +<li>One +<li>Two +</ol> +!! result +<ol> +<li>One +</li> +<li>Two +</li> +</ol> + +!! end + +!! test +HTML nested bullet list, closed tags (bug 5497) +!! input +<ul> +<li>One</li> +<li>Two: +<ul> +<li>Sub-one</li> +<li>Sub-two</li> +</ul> +</li> +</ul> +!! result +<ul> +<li>One</li> +<li>Two: +<ul> +<li>Sub-one</li> +<li>Sub-two</li> +</ul> +</li> +</ul> + +!! end + +!! test +HTML nested bullet list, open tags (bug 5497) +!! options +disabled +!! input +<ul> +<li>One +<li>Two: +<ul> +<li>Sub-one +<li>Sub-two +</ul> +</ul> +!! result +<ul> +<li>One +</li> +<li>Two: +<ul> +<li>Sub-one +</li> +<li>Sub-two +</li> +</ul> +</li> +</ul> + +!! end + +!! test +HTML nested ordered list, closed tags (bug 5497) +!! input +<ol> +<li>One</li> +<li>Two: +<ol> +<li>Sub-one</li> +<li>Sub-two</li> +</ol> +</li> +</ol> +!! result +<ol> +<li>One</li> +<li>Two: +<ol> +<li>Sub-one</li> +<li>Sub-two</li> +</ol> +</li> +</ol> + +!! end + +!! test +HTML nested ordered list, open tags (bug 5497) +!! options +disabled +!! input +<ol> +<li>One +<li>Two: +<ol> +<li>Sub-one +<li>Sub-two +</ol> +</ol> +!! result +<ol> +<li>One +</li> +<li>Two: +<ol> +<li>Sub-one +</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> +!! result +<ol><li id="fragment">One</li> +</ol> + +!! end + +!!test +bug 5918: autonumbering +!! input +[http://first/] [http://second] [ftp://ftp] + +ftp://inlineftp + +[mailto:enclosed@mail.tld With target] + +[mailto:enclosed@mail.tld] + +mailto:inline@mail.tld +!! result +<p><a rel="nofollow" class="external autonumber" href="http://first/">[1]</a> <a rel="nofollow" class="external autonumber" href="http://second">[2]</a> <a rel="nofollow" class="external autonumber" href="ftp://ftp">[3]</a> +</p><p><a rel="nofollow" class="external free" href="ftp://inlineftp">ftp://inlineftp</a> +</p><p><a rel="nofollow" class="external text" href="mailto:enclosed@mail.tld">With target</a> +</p><p><a rel="nofollow" class="external autonumber" href="mailto:enclosed@mail.tld">[4]</a> +</p><p><a rel="nofollow" class="external free" href="mailto:inline@mail.tld">mailto:inline@mail.tld</a> +</p> +!! end + + +# +# Security and HTML correctness +# From Nick Jenkins' fuzz testing +# + +!! test +Fuzz testing: Parser13 +!! input +{| +| http://a| +!! result +<table> +<tr> +<td> +</td> +</tr> +</table> + +!! end + +!! test +Fuzz testing: Parser14 +!! input +== onmouseover= == +http://__TOC__ +!! result +<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> +</div> + + +!! end + +!! test +Fuzz testing: Parser14-table +!! input +==a== +{| STYLE=__TOC__ +!! result +<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> + +!! end + +# Known to produce bogus xml (extra </td>) +!! test +Fuzz testing: Parser16 +!! options +noxml +!! input +{| +!https://|||||| +!! result +<table> +<tr> +<th>https://</th> +<th></th> +<th></th> +<th> +</td> +</tr> +</table> + +!! end + +!! test +Fuzz testing: Parser21 +!! input +{| +! irc://{{ftp://a" onmouseover="alert('hello world');" +| +!! result +<table> +<tr> +<th> <a rel="nofollow" class="external free" href="irc://{{ftp://a">irc://{{ftp://a</a>" onmouseover="alert('hello world');" +</th> +<td> +</td> +</tr> +</table> + +!! end + +!! test +Fuzz testing: Parser22 +!! input +http://===r:::https://b + +{| +!!result +<p><a rel="nofollow" class="external free" href="http://===r:::https://b">http://===r:::https://b</a> +</p> +<table> +<tr><td></td></tr> +</table> + +!! end + +# Known to produce bad XML for now +!! test +Fuzz testing: Parser24 +!! options +noxml +!! input +{| +{{{| +<u CLASS= +| {{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx--><noinclude>}}}} > +<br style="onmouseover='alert(document.cookie);' " /> + +MOVE YOUR MOUSE CURSOR OVER THIS TEXT +| +!! result +<table> +{{{| +<u class="|">}}}} > +<br style="onmouseover='alert(document.cookie);'" /> + +MOVE YOUR MOUSE CURSOR OVER THIS TEXT +<tr> +<td></u> +</td> +</tr> +</table> + +!! end + +# Note: the current result listed for this is not what the original one was, +# but the original bug was JavaScript injection, which is fixed in any case. +# It's not clear that the original result listed was any more correct than the +# current one. Original result: +# <p>{{{| +# </p> +# <li class="||"> +# }}}blah" onmouseover="alert('hello world');" align="left"<b>MOVE MOUSE CURSOR OVER HERE</b> +!!test +Fuzz testing: Parser25 (bug 6055) +!! input +{{{ +| +<LI CLASS=|| + > +}}}blah" onmouseover="alert('hello world');" align="left"'''MOVE MOUSE CURSOR OVER HERE +!! result +<p><LI CLASS=blah" onmouseover="alert('hello world');" align="left"<b>MOVE MOUSE CURSOR OVER HERE</b> +</p> +!! end + +!!test +Fuzz testing: URL adjacent extension (with space, clean) +!! options +!! input +http://example.com <nowiki>junk</nowiki> +!! result +<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a> junk +</p> +!!end + +!!test +Fuzz testing: URL adjacent extension (no space, dirty; nowiki) +!! options +!! input +http://example.com<nowiki>junk</nowiki> +!! result +<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a>junk +</p> +!!end + +!!test +Fuzz testing: URL adjacent extension (no space, dirty; pre) +!! options +!! input +http://example.com<pre>junk</pre> +!! result +<a rel="nofollow" class="external free" href="http://example.com">http://example.com</a><pre>junk</pre> + +!!end + +!!test +Fuzz testing: image with bogus manual thumbnail +!!input +[[Image:foobar.jpg|thumbnail= ]] +!!result +<div class="thumb tright"><div class="thumbinner" style="width:182px;">Error creating thumbnail: <div class="thumbcaption"></div></div></div> + +!!end + +!! test +Fuzz testing: encoded newline in generated HTML replacements (bug 6577) +!! input +<pre dir=" "></pre> +!! result +<pre dir=" "></pre> + +!! end + +!! test +Parsing optional HTML elements (Bug 6171) +!! options +!! input +<table> + <tr> + <td> Some tabular data</td> + <td> More tabular data ... + <td> And yet som tabular data</td> + </tr> +</table> +!! result +<table> + <tr> + <td> Some tabular data</td> + <td> More tabular data ... + </td><td> And yet som tabular data</td> + </tr> +</table> + +!! end + +!! test +Correct handling of <td>, <tr> (Bug 6171) +!! options +!! input +<table> + <tr> + <td> Some tabular data</td> + <td> More tabular data ...</td> + <td> And yet som tabular data</td> + </tr> +</table> +!! result +<table> + <tr> + <td> Some tabular data</td> + <td> More tabular data ...</td> + <td> And yet som tabular data</td> + </tr> +</table> + +!! end + + +!! test +Parsing crashing regression (fr:JavaScript) +!! input +</body></x> +!! result +<p></body></x> +</p> +!! end + +!! test +Inline wiki vs wiki block nesting +!! input +'''Bold paragraph + +New wiki paragraph +!! result +<p><b>Bold paragraph</b> +</p><p>New wiki paragraph +</p> +!! end + +!! test +Inline HTML vs wiki block nesting +!! options +disabled +!! input +<b>Bold paragraph + +New wiki paragraph +!! result +<p><b>Bold paragraph</b> +</p><p>New wiki paragraph +</p> +!! end + +# Original result was this: +# <p><b>bold</b><b>bold<i>bolditalics</i></b> +# </p> +# While that might be marginally more intuitive, maybe, the six-apostrophe +# construct is clearly pathological and the result stated here (which is what +# the parser actually does) is about as reasonable as anything. +!!test +Mixing markup for italics and bold +!! options +!! input +'''bold''''''bold''bolditalics''''' +!! result +<p>'<i>bold'</i><b>bold<i>bolditalics</i></b> +</p> +!! end + + +!! article +Xyzzyx +!! text +Article for special page transclusion test +!! endarticle + +!! test +Special page transclusion +!! options +!! input +{{Special:Prefixindex/Xyzzyx}} +!! result +<table id="mw-prefixindex-list-table"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table> + +!! end + +!! test +Special page transclusion twice (bug 5021) +!! options +!! input +{{Special:Prefixindex/Xyzzyx}} +{{Special:Prefixindex/Xyzzyx}} +!! result +<table id="mw-prefixindex-list-table"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table> +<table id="mw-prefixindex-list-table"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table> + +!! end + +!! test +Transclusion of default MediaWiki message +!! input +{{MediaWiki:Mainpage}} +!!result +<p>Main Page +</p> +!! end + +!! test +Transclusion of nonexistent MediaWiki message +!! input +{{MediaWiki:Mainpagexxx}} +!!result +<p><a href="/index.php?title=MediaWiki:Mainpagexxx&action=edit&redlink=1" class="new" title="MediaWiki:Mainpagexxx (page does not exist)">MediaWiki:Mainpagexxx</a> +</p> +!! end + +!! test +Transclusion of MediaWiki message with underscore +!! input +{{MediaWiki:history_short}} +!! result +<p>History +</p> +!! end + +!! test +Transclusion of MediaWiki message with space +!! input +{{MediaWiki:history short}} +!! result +<p>History +</p> +!! end + +!! test +Invalid header with following text +!! input += x = y +!! result +<p>= x = y +</p> +!! end + + +!! test +Section extraction test (section 0) +!! options +section=0 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +!! end + +!! test +Section extraction test (section 1) +!! options +section=1 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +==a== +===aa=== +====aaa==== +!! end + +!! test +Section extraction test (section 2) +!! options +section=2 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +===aa=== +====aaa==== +!! end + +!! test +Section extraction test (section 3) +!! options +section=3 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +====aaa==== +!! end + +!! test +Section extraction test (section 4) +!! options +section=4 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +==b== +===ba=== +===bb=== +====bba==== +===bc=== +!! end + +!! test +Section extraction test (section 5) +!! options +section=5 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +===ba=== +!! end + +!! test +Section extraction test (section 6) +!! options +section=6 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +===bb=== +====bba==== +!! end + +!! test +Section extraction test (section 7) +!! options +section=7 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +====bba==== +!! end + +!! test +Section extraction test (section 8) +!! options +section=8 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +===bc=== +!! end + +!! test +Section extraction test (section 9) +!! options +section=9 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +==c== +===ca=== +!! end + +!! test +Section extraction test (section 10) +!! options +section=10 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +===ca=== +!! end + +!! test +Section extraction test (nonexistent section 11) +!! options +section=11 +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +!! end + +!! test +Section extraction test with bogus heading (section 1) +!! options +section=1 +!! input +==a== +==bogus== not a legal section +==b== +!! result +==a== +==bogus== not a legal section +!! end + +!! test +Section extraction test with bogus heading (section 2) +!! options +section=2 +!! input +==a== +==bogus== not a legal section +==b== +!! result +==b== +!! end + +!! test +Section extraction test with comment after heading (section 1) +!! options +section=1 +!! input +==a== +==b== <!-- --> +==c== +!! result +==a== +!! end + +!! test +Section extraction test with comment after heading (section 2) +!! options +section=2 +!! input +==a== +==b== <!-- --> +==c== +!! result +==b== <!-- --> +!! end + +!! test +Section extraction test with bogus <nowiki> heading (section 1) +!! options +section=1 +!! input +==a== +==bogus== <nowiki>not a legal section</nowiki> +==b== +!! result +==a== +==bogus== <nowiki>not a legal section</nowiki> +!! end + +!! test +Section extraction test with bogus <nowiki> heading (section 2) +!! options +section=2 +!! input +==a== +==bogus== <nowiki>not a legal section</nowiki> +==b== +!! result +==b== +!! end + + +# Formerly testing for bug 2587, now resolved by the use of unmarked sections +# instead of respecting commented sections +!! test +Section extraction prefixed by comment (section 1) +!! options +section=1 +!! input +<!-- -->==sec1== +==sec2== +!!result +==sec2== +!!end + +!! test +Section extraction prefixed by comment (section 2) +!! options +section=2 +!! input +<!-- -->==sec1== +==sec2== +!!result + +!!end + + +# Formerly testing for bug 2607, now resolved by the use of unmarked sections +# instead of respecting HTML-style headings +!! test +Section extraction, mixed wiki and html (section 1) +!! options +section=1 +!! input +<h2>unmarked</h2> +unmarked +==1== +one +==2== +two +!! result +==1== +one +!! end + +!! test +Section extraction, mixed wiki and html (section 2) +!! options +section=2 +!! input +<h2>unmarked</h2> +unmarked +==1== +one +==2== +two +!! result +==2== +two +!! end + + +# Formerly testing for bug 3342 +!! test +Section extraction, heading surrounded by <noinclude> +!! options +section=1 +!! input +<noinclude>==unmarked==</noinclude> +==marked== +!! result +==marked== +!!end + +# Test behavior of bug 19910 +!! test +Sectiion with all-equals +!! options +section=2 +!! input +=== +The line above must have a trailing space +=== <!-- +--> <!-- --> +But just in case it doesn't... +!! result +=== <!-- +--> <!-- --> +But just in case it doesn't... +!! end + +!! test +Section replacement test (section 0) +!! options +replace=0,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +xxx + +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 1) +!! options +replace=1,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +xxx + +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 2) +!! options +replace=2,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +xxx + +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 3) +!! options +replace=3,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +xxx + +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 4) +!! options +replace=4,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +xxx + +==c== +===ca=== +!! end + +!! test +Section replacement test (section 5) +!! options +replace=5,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +xxx + +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 6) +!! options +replace=6,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +xxx + +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 7) +!! options +replace=7,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +xxx + +===bc=== +==c== +===ca=== +!! end + +!! test +Section replacement test (section 8) +!! options +replace=8,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +xxx + +==c== +===ca=== +!!end + +!! test +Section replacement test (section 9) +!! options +replace=9,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +xxx +!! end + +!! test +Section replacement test (section 10) +!! options +replace=10,"xxx" +!! input +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +===ca=== +!! result +start +==a== +===aa=== +====aaa==== +==b== +===ba=== +===bb=== +====bba==== +===bc=== +==c== +xxx +!! end + +!! test +Section replacement test with initial whitespace (bug 13728) +!! options +replace=2,"xxx" +!! input + Preformatted initial line +==a== +===a=== +!! result + Preformatted initial line +==a== +xxx +!! end + + +!! test +Section extraction, heading followed by pre with 20 spaces (bug 6398) +!! options +section=1 +!! input +==a== + a +!! result +==a== + a +!! end + +!! test +Section extraction, heading followed by pre with 19 spaces (bug 6398 sanity check) +!! options +section=1 +!! input +==a== + a +!! result +==a== + a +!! end + + +!! test +Section extraction, <pre> around bogus header (bug 10309) +!! options +noxml section=2 +!! input +== Section One == +<pre> +======= +</pre> + +== Section Two == +stuff +!! result +== Section Two == +stuff +!! end + +!! test +Section replacement, <pre> around bogus header (bug 10309) +!! options +noxml replace=2,"xxx" +!! input +== Section One == +<pre> +======= +</pre> + +== Section Two == +stuff +!! result +== Section One == +<pre> +======= +</pre> + +xxx +!! end + + + +!! test +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> + +!!end + +!! test +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 +Special:Search page linking. +!! input +{{Special:search}} +!! result +<p><a href="/wiki/Special:Search" title="Special:Search">Special:Search</a> +</p> +!! end + +!! test +Say the magic word +!! options +title=[[Parser test]] +!! input +* {{PAGENAME}} +* {{PAGENAMEE}} +* {{FULLPAGENAME}} +* {{FULLPAGENAMEE}} +* {{BASEPAGENAME}} +* {{BASEPAGENAMEE}} +* {{SUBPAGENAME}} +* {{SUBPAGENAMEE}} +* {{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> 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. + +!! test +Gallery +!! input +<gallery> +image1.png | +image2.gif||||| + +image3| +image4 |300px| centre + image5.svg| http:///////// +[[x|xx]]]] +* image6 +</gallery> +!! result +<ul class="gallery mw-gallery-traditional"> + <li class="gallerybox" style="width: 155px"><div style="width: 155px"> + <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 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 class="thumb" style="height: 150px;">Image3</div> + <div class="gallerytext"> + </div> + </div></li> + <li class="gallerybox" style="width: 155px"><div style="width: 155px"> + <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 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 class="thumb" style="height: 150px;">* image6</div> + <div class="gallerytext"> + </div> + </div></li> +</ul> + +!! end + +!! test +Gallery (with options) +!! input +<gallery widths='70px' heights='40px' perrow='2' caption='Foo [[Main Page]]' > +File:Nonexistant.jpg|caption +File:Nonexistant.jpg +image:foobar.jpg|some '''caption''' [[Main Page]] +image:foobar.jpg +image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla. +</gallery> +!! result +<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 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 class="thumb" style="height: 70px;">Nonexistant.jpg</div> + <div class="gallerytext"> + </div> + </div></li> + <li class="gallerybox" style="width: 105px"><div style="width: 105px"> + <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div> + <div class="gallerytext"> +<p>some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p> + </div> + </div></li> + <li class="gallerybox" style="width: 105px"><div style="width: 105px"> + <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div> + <div class="gallerytext"> + </div> + </div></li> + <li class="gallerybox" style="width: 105px"><div style="width: 105px"> + <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a foo-bar." src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div> + <div class="gallerytext"> +<p>Blabla|blabla. +</p> + </div> + </div></li> +</ul> + +!! end + +!! test +Gallery with wikitext inside caption +!! input +<gallery> +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 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"> +<p><a href="/wiki/File:Foobar.jpg" class="image" title="desc"><img alt="inneralt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" width="20" height="2" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/30px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/40px-Foobar.jpg 2x" /></a> +</p> + </div> + </div></li> + <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"> +<p>This is a test template +</p> + </div> + </div></li> +</ul> + +!! end + +!! test +gallery (with showfilename option) +!! input +<gallery showfilename> +File:Nonexistant.jpg|caption +File:Nonexistant.jpg +image:foobar.jpg|some '''caption''' [[Main Page]] +File:Foobar.jpg +</gallery> +!! result +<ul class="gallery mw-gallery-traditional"> + <li class="gallerybox" style="width: 155px"><div style="width: 155px"> + <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 +</p> + </div> + </div></li> + <li class="gallerybox" style="width: 155px"><div style="width: 155px"> + <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> + </div> + </div></li> + <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="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div> + <div class="gallerytext"> +<p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br /> +some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p> + </div> + </div></li> + <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"> +<p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br /> +</p> + </div> + </div></li> +</ul> + +!! end + +!! test +Gallery (with namespace-less filenames) +!! input +<gallery> +File:Nonexistant.jpg +Nonexistant.jpg +image:foobar.jpg +foobar.jpg +</gallery> +!! result +<ul class="gallery mw-gallery-traditional"> + <li class="gallerybox" style="width: 155px"><div style="width: 155px"> + <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 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 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"> + </div> + </div></li> + <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"> + </div> + </div></li> +</ul> + +!! end + +!! test +HTML Hex character encoding (spells the word "JavaScript") +!! input +JavaScript +!! result +<p>JavaScript +</p> +!! end + +!! test +HTML Hex character encoding bogus encoding (bug 26437 regression check) +!! input +&#xsee;&#XSEE; +!! result +<p>&#xsee;&#XSEE; +</p> +!! end + +!! test +HTML Hex character encoding mixed case +!! input +îî +!! result +<p>îî +</p> +!! end + +!! test +__FORCETOC__ override +!! input +__NEWSECTIONLINK__ +__FORCETOC__ +!! result +<p><br /> +</p> +!! end + +!! test +ISBN code coverage +!! input +ISBN 978-0-1234-56 789 +!! result +<p><a href="/wiki/Special:BookSources/9780123456" class="internal mw-magiclink-isbn">ISBN 978-0-1234-56</a> 789 +</p> +!! end + +!! test +ISBN followed by 5 spaces +!! input +ISBN +!! result +<p>ISBN +</p> +!! end + +!! test +Double ISBN +!! input +ISBN ISBN 1234567890 +!! result +<p>ISBN <a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1234567890</a> +</p> +!! end + +!! test +Bug 22905: <abbr> followed by ISBN followed by </a> +!! input +<abbr>(fr)</abbr> ISBN 2753300917 [http://www.example.com example.com] +!! result +<p><abbr>(fr)</abbr> <a href="/wiki/Special:BookSources/2753300917" class="internal mw-magiclink-isbn">ISBN 2753300917</a> <a rel="nofollow" class="external text" href="http://www.example.com">example.com</a> +</p> +!! end + +!! test +Double RFC +!! input +RFC RFC 1234 +!! result +<p>RFC <a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc1234">RFC 1234</a> +</p> +!! end + +!! test +Double RFC with a wiki link +!! input +RFC [[RFC 1234]] +!! result +<p>RFC <a href="/index.php?title=RFC_1234&action=edit&redlink=1" class="new" title="RFC 1234 (page does not exist)">RFC 1234</a> +</p> +!! end + +!! test +RFC code coverage +!! input +RFC 983 987 +!! result +<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc983">RFC 983</a> 987 +</p> +!! end + +!! test +Centre-aligned image +!! input +[[Image:foobar.jpg|centre]] +!! result +<div class="center"><div class="floatnone"><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></div> + +!!end + +!! test +None-aligned image +!! input +[[Image:foobar.jpg|none]] +!! result +<div class="floatnone"><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 +Width + Height sized image (using px) (height is ignored) +!! input +[[Image:foobar.jpg|640x480px]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a> +</p> +!!end + +!! test +Width-sized image (using px, no following whitespace) +!! input +[[Image:foobar.jpg|640px]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a> +</p> +!!end + +!! test +Width-sized image (using px, with following whitespace - test regression from r39467) +!! input +[[Image:foobar.jpg|640px ]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a> +</p> +!!end + +!! test +Width-sized image (using px, with preceding whitespace - test regression from r39467) +!! input +[[Image:foobar.jpg| 640px]] +!! result +<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a> +</p> +!!end + +!! test +Another italics / bold test +!! input + ''' ''x' +!! result +<pre>'<i> </i>x' +</pre> +!!end + +# Note the results may be incorrect, as parserTest output included this: +# XML error: Mismatched tag at byte 6120: +# ...<dd> </dt></dl> </dd... +!! test +dt/dd/dl test +!! options +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> + +!!end + + +# Images with the "|" character in external URLs in comment tags; Eats half the comment, leaves unmatched "</a>" tag. +!! test +Images with the "|" character in the comment +!! input +[[image:Foobar.jpg|thumb|An [http://test/?param1=|left|¶m2=|x external] URL]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&param2=%7Cx">external</a> URL</div></div></div> + +!!end + +!! test +[Before] HTML without raw HTML enabled ($wgRawHtml==false) +!! input +<html><script>alert(1);</script></html> +!! result +<p><html><script>alert(1);</script></html> +</p> +!! end + +!! test +HTML with raw HTML ($wgRawHtml==true) +!! options +wgRawHtml=1 +!! input +<html><script>alert(1);</script></html> +!! result +<p><script>alert(1);</script> +</p> +!! end + +!! test +Parents of subpages, one level up +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +[[../|L2]] +!! result +<p><a href="/index.php?title=Subpage_test/L1/L2&action=edit&redlink=1" class="new" title="Subpage test/L1/L2 (page does not exist)">L2</a> +</p> +!! end + + +!! test +Parents of subpages, one level up, not named +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +[[../]] +!! result +<p><a href="/index.php?title=Subpage_test/L1/L2&action=edit&redlink=1" class="new" title="Subpage test/L1/L2 (page does not exist)">Subpage test/L1/L2</a> +</p> +!! end + + + +!! test +Parents of subpages, two levels up +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +[[../../|L1]]2 + +[[../../|L1]]l +!! result +<p><a href="/index.php?title=Subpage_test/L1&action=edit&redlink=1" class="new" title="Subpage test/L1 (page does not exist)">L1</a>2 +</p><p><a href="/index.php?title=Subpage_test/L1&action=edit&redlink=1" class="new" title="Subpage test/L1 (page does not exist)">L1l</a> +</p> +!! end + +!! test +Parents of subpages, two levels up, without trailing slash or name. +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +[[../..]] +!! result +<p>[[../..]] +</p> +!! end + +!! test +Parents of subpages, two levels up, with lots of extra trailing slashes. +!! options +subpage title=[[Subpage test/L1/L2/L3]] +!! input +[[../../////]] +!! result +<p><a href="/index.php?title=Subpage_test/L1////&action=edit&redlink=1" class="new" title="Subpage test/L1//// (page does not exist)">///</a> +</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 +; title : def +; 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> + +!! end + +!! test +Don't fall for the self-closing div +!! input +<div>hello world</div/> +!! result +<div>hello world</div> + +!! end + +!! test +MSGNW magic word +!! input +{{MSGNW:msg}} +!! result +<p>[[:Template:Msg]] +</p> +!! end + +!! test +RAW magic word +!! input +{{RAW:QUERTY}} +!! result +<p><a href="/index.php?title=Template:QUERTY&action=edit&redlink=1" class="new" title="Template:QUERTY (page does not exist)">Template:QUERTY</a> +</p> +!! end + +# This isn't needed for XHTML conformance, but would be handy as a fallback security measure +!! test +Always escape literal '>' in output, not just after '<' +!! input +><> +!! result +<p>><> +</p> +!! end + +!! test +Template caching +!! input +{{Test}} +{{Test}} +!! result +<p>This is a test template +This is a test template +</p> +!! end + + +!! article +MediaWiki:Fake +!! text +==header== +!! endarticle + +!! test +Inclusion of !userCanEdit() content +!! input +{{MediaWiki:Fake}} +!! result +<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 + + +!! test +Out-of-order TOC heading levels +!! input +==2== +======6====== +===3=== +=1= +=====5===== +==2== +!! result +<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> +<li class="toclevel-2 tocsection-2"><a href="#6"><span class="tocnumber">1.1</span> <span class="toctext">6</span></a></li> +<li class="toclevel-2 tocsection-3"><a href="#3"><span class="tocnumber">1.2</span> <span class="toctext">3</span></a></li> +</ul> +</li> +<li class="toclevel-1 tocsection-4"><a href="#1"><span class="tocnumber">2</span> <span class="toctext">1</span></a> +<ul> +<li class="toclevel-2 tocsection-5"><a href="#5"><span class="tocnumber">2.1</span> <span class="toctext">5</span></a></li> +<li class="toclevel-2 tocsection-6"><a href="#2_2"><span class="tocnumber">2.2</span> <span class="toctext">2</span></a></li> +</ul> +</li> +</ul> +</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 + + +!! test +ISBN with a dummy number +!! input +ISBN --- +!! result +<p>ISBN --- +</p> +!! end + + +!! test +ISBN with space-delimited number +!! input +ISBN 92 9017 032 8 +!! result +<p><a href="/wiki/Special:BookSources/9290170328" class="internal mw-magiclink-isbn">ISBN 92 9017 032 8</a> +</p> +!! end + + +!! test +ISBN with multiple spaces, no number +!! input +ISBN foo +!! result +<p>ISBN foo +</p> +!! end + + +!! test +ISBN length +!! input +ISBN 123456789 + +ISBN 1234567890 + +ISBN 12345678901 +!! result +<p>ISBN 123456789 +</p><p><a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1234567890</a> +</p><p>ISBN 12345678901 +</p> +!! end + + +!! test +ISBN with trailing year (bug 8110) +!! input +ISBN 1-234-56789-0 - 2006 + +ISBN 1 234 56789 0 - 2006 +!! result +<p><a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1-234-56789-0</a> - 2006 +</p><p><a href="/wiki/Special:BookSources/1234567890" class="internal mw-magiclink-isbn">ISBN 1 234 56789 0</a> - 2006 +</p> +!! end + + +!! test +anchorencode +!! input +{{anchorencode:foo bar©#%n}} +!! result +<p>foo_bar.C2.A9.23.25n +</p> +!! end + +!! test +anchorencode trims spaces +!! input +{{anchorencode: __pretty__please__}} +!! result +<p>pretty_please +</p> +!! end + +!! test +anchorencode deals with links +!! input +{{anchorencode: [[hello|world]] [[hi]]}} +!! result +<p>world_hi +</p> +!! end + +!! test +anchorencode deals with templates +!! input +{{anchorencode: {{Foo}} }} +!! result +<p>FOO +</p> +!! end + +!! test +anchorencode encodes like the TOC generator: (bug 18431) +!! input +=== _ +:.3A%3A&&]] === +{{anchorencode: _ +:.3A%3A&&]] }} +__NOEDITSECTION__ +!! result +<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 + +!! test +Bug 6200: blockquotes and paragraph formatting +!! input +<blockquote> +foo +</blockquote> + +bar + + baz +!! result +<blockquote> +<p>foo +</p> +</blockquote> +<p>bar +</p> +<pre>baz +</pre> +!! end + +!! test +Bug 8293: Use of center tag ruins paragraph formatting +!! input +<center> +foo +</center> + +bar + + baz +!! result +<center> +<p>foo +</p> +</center> +<p>bar +</p> +<pre>baz +</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 +### +!! test +Self-link in language variants +!! options +title=[[Dunav]] language=sr +!! input +Both [[Dunav]] and [[Дунав]] are names for this river. +!! result +<p>Both <strong class="selflink">Dunav</strong> and <strong class="selflink">Дунав</strong> are names for this river. +</p> +!!end + +!! article +Дуна +!! text +content +!! endarticle + +!! test +Link to another existing title shouldn't be parsed as self-link even if it's a variant of this title +!! options +title=[[Duna]] language=sr +!! input +[[Дуна]] is not a self-link while [[Duna]] and [[Dуна]] are still self-links. +!! result +<p><a href="/wiki/%D0%94%D1%83%D0%BD%D0%B0" title="Дуна">Дуна</a> is not a self-link while <strong class="selflink">Duna</strong> and <strong class="selflink">Dуна</strong> are still self-links. +</p> +!! 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 +!! input +Main Page can be written as [[Маин Паге]] +!! result +<p>Main Page can be written as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a> +</p> +!!end + + +!! test +Multiple links to pages in language variants +!! options +language=sr +!! input +[[Main Page]] can be written as [[Маин Паге]] same as [[Маин Паге]]. +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> can be written as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a> same as <a href="/wiki/Main_Page" title="Main Page">Маин Паге</a>. +</p> +!!end + + +!! test +Simple template in language variants +!! options +language=sr +!! input +{{тест}} +!! result +<p>This is a test template +</p> +!! end + + +!! test +Template with explicit namespace in language variants +!! options +language=sr +!! input +{{Template:тест}} +!! result +<p>This is a test template +</p> +!! end + + +!! test +Basic test for template parameter in language variants +!! options +language=sr +!! input +{{парамтест|param=foo}} +!! result +<p>This is a test template with parameter foo +</p> +!! end + + +!! test +Simple category in language variants +!! options +language=sr cat +!! input +[[Category:МедиаWики Усер'с Гуиде]] +!! result +<a href="/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%98%D0%B0:MediaWiki_User%27s_Guide" title="Категорија:MediaWiki User's Guide">MediaWiki User's Guide</a> +!! end + + +!! article +Category:分类 +!! text +blah +!! endarticle + +!! article +Category:分類 +!! text +blah +!! endarticle + +!! test +Don't convert blue categorylinks to another variant (bug 33210) +!! options +language=zh cat +!! input +[[A]][[Category:分类]] +!! result +<a href="/wiki/Category:%E5%88%86%E7%B1%BB" title="Category:分类">分类</a> +!! end + + +!! test +Stripping -{}- tags (language variants) +!! options +language=sr +!! input +Latin proverb: -{Ne nuntium necare}- +!! result +<p>Latin proverb: Ne nuntium necare +</p> +!! end + + +!! test +Prevent conversion with -{}- tags (language variants) +!! options +language=sr variant=sr-ec +!! input +Latinski: -{Ne nuntium necare}- +!! result +<p>Латински: Ne nuntium necare +</p> +!! end + + +!! test +Prevent conversion of text with -{}- tags (language variants) +!! options +language=sr variant=sr-ec +!! input +Latinski: -{Ne nuntium necare}- +!! result +<p>Латински: Ne nuntium necare +</p> +!! end + + +!! test +Prevent conversion of links with -{}- tags (language variants) +!! options +language=sr variant=sr-ec +!! input +-{[[Main Page]]}- +!! result +<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a> +</p> +!! end + + +!! test +-{}- tags within headlines (within html for parserConvert()) +!! options +language=sr variant=sr-ec +!! input +== -{Naslov}- == +!! result +<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 + + +!! test +Explicit definition of language variant alternatives +!! options +language=zh variant=zh-tw +!! input +-{zh:China;zh-tw:Taiwan}-, not China +!! result +<p>Taiwan, not China +</p> +!! end + + +!! test +Conversion around HTML tags +!! options +language=sr variant=sr-ec +!! input +-{H|span=>sr-ec:script;title=>sr-ec:src;}- +<span title="La-{sr-el:L;sr-ec:C;}-tin">ski</span> +!! result +<p> +<span title="ЛаCтин">ски</span> +</p> +!! end + + +!! test +Explicit session-wise language variant mapping (A flag and - flag) +!! options +language=zh variant=zh-tw +!! input +Taiwan is not China. +But -{A|zh:China;zh-tw:Taiwan}- is China, +(This-{-|zh:China;zh-tw:Taiwan}- should be stripped!) +and -{China}- is China. +!! result +<p>Taiwan is not China. +But Taiwan is Taiwan, +(This should be stripped!) +and China is China. +</p> +!! end + +!! test +Explicit session-wise language variant mapping (H flag for hide) +!! options +language=zh variant=zh-tw +!! input +(This-{H|zh:China;zh-tw:Taiwan}- should be stripped!) +Taiwan is China. +!! result +<p>(This should be stripped!) +Taiwan is Taiwan. +</p> +!! end + +!! test +Adding explicit conversion rule for title (T flag) +!! options +language=zh variant=zh-tw showtitle +!! input +Should be stripped-{T|zh:China;zh-tw:Taiwan}-! +!! result +Taiwan +<p>Should be stripped! +</p> +!! end + +!! test +Testing that changing the language variant here in the tests actually works +!! options +language=zh variant=zh showtitle +!! input +Should be stripped-{T|zh:China;zh-tw:Taiwan}-! +!! result +China +<p>Should be stripped! +</p> +!! end + +!! test +Recursive conversion of alt and title attrs shouldn't clear converter state +!! options +language=zh variant=zh-cn showtitle +!! input +-{H|zh-cn:Exclamation;zh-tw:exclamation;}- +Should be stripped-{T|zh-cn:China;zh-tw:Taiwan}-<span title="exclamation">!</span> +!! result +China +<p> +Should be stripped<span title="Exclamation">!</span> +</p> +!! end + +!! test +Bug 24072: more test on conversion rule for title +!! options +language=zh variant=zh-tw showtitle +!! input +This should be stripped-{T|zh:China;zh-tw:Taiwan}-! +This won't take interferes with the title rule-{H|zh:Beijing;zh-tw:Taipei}-. +!! result +Taiwan +<p>This should be stripped! +This won't take interferes with the title rule. +</p> +!! 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 +!! input +Raw: -{R|zh:China;zh-tw:Taiwan}- +!! result +<p>Raw: zh:China;zh-tw:Taiwan +</p> +!! end + +!! test +Nested using of manual convert syntax +!! options +language=zh variant=zh-hk +!! input +Nested: -{zh-hans:Hi -{zh-cn:China;zh-sg:Singapore;}-;zh-hant:Hello -{zh-tw:Taiwan;zh-hk:H-{ong}- K-{}-ong;}-;}-! +!! result +<p>Nested: Hello Hong Kong! +</p> +!! end + +!! test +Proper conversion of text in external links +!! options +language=sr variant=sr-ec +!! input +http://www.google.com +gopher://www.google.com +[http://www.google.com http://www.google.com] +[gopher://www.google.com gopher://www.google.com] +[https://www.google.com irc://www.google.com] +[ftp://www.google.com www.google.com/ftp://dir] +[//www.google.com www.google.com] +!! result +<p><a rel="nofollow" class="external free" href="http://www.google.com">http://www.google.com</a> +<a rel="nofollow" class="external free" href="gopher://www.google.com">gopher://www.google.com</a> +<a rel="nofollow" class="external free" href="http://www.google.com">http://www.google.com</a> +<a rel="nofollow" class="external free" href="gopher://www.google.com">gopher://www.google.com</a> +<a rel="nofollow" class="external text" href="https://www.google.com">irc://www.google.com</a> +<a rel="nofollow" class="external text" href="ftp://www.google.com">www.гоогле.цом/фтп://дир</a> +<a rel="nofollow" class="external text" href="//www.google.com">www.гоогле.цом</a> +</p> +!! end + +!! test +Do not convert roman numbers to language variants +!! options +language=sr variant=sr-ec +!! input +Fridrih IV je car. +!! result +<p>Фридрих IV је цар. +</p> +!! end + +!! test +Unclosed language converter markup "-{" +!! options +language=sr +!! input +-{T|hello +!! result +<p>-{T|hello +</p> +!! end + +!! test +Don't convert raw rule "-{R|=>}-" to "=>" +!! options +language=sr +!! input +-{R|=>}- +!! result +<p>=> +</p> +!!end + +!! test +Bug 529: Uncovered bullet +!! input +* Foo {{bullet}} +!! result +<ul> +<li> Foo +</li> +<li> Bar +</li> +</ul> + +!! end + +# Plain MediaWiki does not remove empty lists, but tidy actually does. +# Templates in Wikipedia rely on this behavior, as tidy has always been +# enabled there. These tests are normally run *without* tidy, so specify the +# full output here. +# To test realistic parsing behavior, apply a tidy-like transformation to both +# the expected output and your parser's output. +!! test +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> + +!! end + +!! test +Bug 529: Uncovered table already at line-start +!! input +x + +{{table}} +y +!! result +<p>x +</p> +<table> +<tr> +<td> 1 </td> +<td> 2 +</td></tr> +<tr> +<td> 3 </td> +<td> 4 +</td></tr></table> +<p>y +</p> +!! end + +!! test +Bug 529: Uncovered bullet in parser function result +!! input +* Foo {{lc:{{bullet}} }} +!! result +<ul> +<li> Foo +</li> +<li> bar +</li> +</ul> + +!! end + +!! test +Bug 5678: Double-parsed template argument +!! input +{{lc:{{{1}}}|hello}} +!! result +<p>{{{1}}} +</p> +!! end + +!! test +Bug 5678: Double-parsed template invocation +!! input +{{lc:{{paramtest {{!}} param = hello }} }} +!! result +<p>{{paramtest | param = hello }} +</p> +!! end + +!! test +Case insensitivity of parser functions for non-ASCII characters (bug 8143) +!! options +language=cs +title=[[Main Page]] +!! input +{{PRVNÍVELKÉ:ěščř}} +{{prvnívelké:ěščř}} +{{PRVNÍMALÉ:ěščř}} +{{prvnímalé:ěščř}} +{{MALÁ:ěščř}} +{{malá:ěščř}} +{{VELKÁ:ěščř}} +{{velká:ěščř}} +!! result +<p>Ěščř +Ěščř +ěščř +ěščř +ěščř +ěščř +ĚŠČŘ +ĚŠČŘ +</p> +!! end + +!! test +Morwen/13: Unclosed link followed by heading +!! input +[[link +==heading== +!! result +<p>[[link +</p> +<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 + +!! test +HHP2.1: Heuristics for headings in preprocessor parenthetical structures +!! input +{{foo| +=heading= +!! result +<p>{{foo| +</p> +<h1><span class="mw-headline" id="heading">heading</span></h1> + +!! end + +!! test +HHP2.2: Heuristics for headings in preprocessor parenthetical structures +!! input +{{foo| +==heading== +!! result +<p>{{foo| +</p> +<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 + +!! test +Tildes in comments +!! options +pst +!! input +<!-- ~~~~ --> +!! result +<!-- ~~~~ --> +!! end + +!! test +Paragraphs inside divs (no extra line breaks) +!! input +<div>Line one + +Line two</div> +!! result +<div>Line one +Line two</div> + +!! end + +!! test +Paragraphs inside divs (extra line break on open) +!! input +<div> +Line one + +Line two</div> +!! result +<div> +<p>Line one +</p> +Line two</div> + +!! end + +!! test +Paragraphs inside divs (extra line break on close) +!! input +<div>Line one + +Line two +</div> +!! result +<div>Line one +<p>Line two +</p> +</div> + +!! end + +!! test +Paragraphs inside divs (extra line break on open and close) +!! input +<div> +Line one + +Line two +</div> +!! result +<div> +<p>Line one +</p><p>Line two +</p> +</div> + +!! end + +!! test +Nesting tags, paragraphs on lines which begin with <div> +!! options +disabled +!! input +<div></div><strong>A +B</strong> +!! result +<div></div> +<p><strong>A +B</strong> +</p> +!! end + +# Bug 6200: <blockquote> should behave like <div> with respect to line breaks +!! test +Bug 6200: paragraphs inside blockquotes (no extra line breaks) +!! input +<blockquote>Line one + +Line two</blockquote> +!! result +<blockquote>Line one +Line two</blockquote> + +!! end + +!! test +Bug 6200: paragraphs inside blockquotes (extra line break on open) +!! input +<blockquote> +Line one + +Line two</blockquote> +!! result +<blockquote> +<p>Line one +</p> +Line two</blockquote> + +!! end + +!! test +Bug 6200: paragraphs inside blockquotes (extra line break on close) +!! input +<blockquote>Line one + +Line two +</blockquote> +!! result +<blockquote>Line one +<p>Line two +</p> +</blockquote> + +!! end + +!! test +Bug 6200: paragraphs inside blockquotes (extra line break on open and close) +!! input +<blockquote> +Line one + +Line two +</blockquote> +!! result +<blockquote> +<p>Line one +</p><p>Line two +</p> +</blockquote> + +!! end + +!! test +Paragraphs inside blockquotes/divs (no extra line breaks) +!! input +<blockquote><div>Line one + +Line two</div></blockquote> +!! result +<blockquote><div>Line one +Line two</div></blockquote> + +!! end + +!! test +Paragraphs inside blockquotes/divs (extra line break on open) +!! input +<blockquote><div> +Line one + +Line two</div></blockquote> +!! result +<blockquote><div> +<p>Line one +</p> +Line two</div></blockquote> + +!! end + +!! test +Paragraphs inside blockquotes/divs (extra line break on close) +!! input +<blockquote><div>Line one + +Line two +</div></blockquote> +!! result +<blockquote><div>Line one +<p>Line two +</p> +</div></blockquote> + +!! end + +!! test +Paragraphs inside blockquotes/divs (extra line break on open and close) +!! input +<blockquote><div> +Line one + +Line two +</div></blockquote> +!! result +<blockquote><div> +<p>Line one +</p><p>Line two +</p> +</div></blockquote> + +!! end + +!! test +Interwiki links trounced by replaceExternalLinks after early LinkHolderArray expansion +!! options +wgLinkHolderBatchSize=0 +!! input +[[meatball:1]] +[[meatball:2]] +[[meatball:3]] +!! result +<p><a href="http://www.usemod.com/cgi-bin/mb.pl?1" class="extiw" title="meatball:1">meatball:1</a> +<a href="http://www.usemod.com/cgi-bin/mb.pl?2" class="extiw" title="meatball:2">meatball:2</a> +<a href="http://www.usemod.com/cgi-bin/mb.pl?3" class="extiw" title="meatball:3">meatball:3</a> +</p> +!! end + +!! test +Free external link invading image caption +!! input +[[Image:Foobar.jpg|thumb|http://x|hello]] +!! result +<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></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>hello</div></div></div> + +!! end + +!! test +Bug 15196: localised external link numbers +!! options +language=fa +!! input +[http://en.wikipedia.org/] +!! result +<p><a rel="nofollow" class="external autonumber" href="http://en.wikipedia.org/">[۱]</a> +</p> +!! end + +!! test +Multibyte character in padleft +!! input +{{padleft:-Hello|7|Æ}} +!! result +<p>Æ-Hello +</p> +!! end + +!! test +Multibyte character in padright +!! input +{{padright:Hello-|7|Æ}} +!! result +<p>Hello-Æ +</p> +!! end + +!!test +formatdate parser function +!!input +{{#formatdate:2009-03-24}} +!! result +<p><span class="mw-formatted-date" title="2009-03-24">2009-03-24</span> +</p> +!! end + +!!test +formatdate parser function, with default format +!!input +{{#formatdate:2009-03-24|mdy}} +!! result +<p><span class="mw-formatted-date" title="2009-03-24">March 24, 2009</span> +</p> +!! end + +!! test +Spacing of numbers in formatted dates +!! input +{{#formatdate:January 15}} +!! result +<p><span class="mw-formatted-date" title="01-15">January 15</span> +</p> +!! end + +!! test +formatdate parser function, with default format and on a page of which the content language is always English and different from the wiki content language +!! options +language=nl title=[[MediaWiki:Common.css]] +!! input +{{#formatdate:2009-03-24|dmy}} +!! result +<p><span class="mw-formatted-date" title="2009-03-24">24 March 2009</span> +</p> +!! end + +# +# +# + +# +# Edit comments +# + +!! test +Edit comment with link +!! options +comment +!! input +I like the [[Main Page]] a lot +!! result +I like the <a href="/wiki/Main_Page" title="Main Page">Main Page</a> a lot +!!end + +!! test +Edit comment with link and link text +!! options +comment +!! input +I like the [[Main Page|best pages]] a lot +!! result +I like the <a href="/wiki/Main_Page" title="Main Page">best pages</a> a lot +!!end + +!! test +Edit comment with link and link text with suffix +!! options +comment +!! input +I like the [[Main Page|best page]]s a lot +!! result +I like the <a href="/wiki/Main_Page" title="Main Page">best pages</a> a lot +!!end + +!! test +Edit comment with section link (non-local, eg in history list) +!! options +comment title=[[Main Page]] +!! input +/* External links */ removed bogus entries +!! result +<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 +Edit comment with section link and text before it (non-local, eg in history list) +!! options +comment title=[[Main Page]] +!! input +pre-comment text /* External links */ removed bogus entries +!! result +pre-comment text <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 +Edit comment with section link (local, eg in diff view) +!! options +comment local title=[[Main Page]] +!! input +/* External links */ removed bogus entries +!! result +<a href="#External_links">→</a><span dir="auto"><span class="autocomment">External links: </span> removed bogus entries</span> +!!end + +!! test +Edit comment with subpage link (bug 14080) +!! options +comment +subpage +title=[[Subpage test]] +!! input +Poked at a [[/subpage]] here... +!! result +Poked at a <a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">/subpage</a> here... +!!end + +!! test +Edit comment with subpage link and link text (bug 14080) +!! options +comment +subpage +title=[[Subpage test]] +!! input +Poked at a [[/subpage|neat little page]] here... +!! result +Poked at a <a href="/wiki/Subpage_test/subpage" title="Subpage test/subpage">neat little page</a> here... +!!end + +!! test +Edit comment with bogus subpage link in non-subpage NS (bug 14080) +!! options +comment +title=[[Subpage test]] +!! input +Poked at a [[/subpage]] here... +!! result +Poked at a <a href="/index.php?title=/subpage&action=edit&redlink=1" class="new" title="/subpage (page does not exist)">/subpage</a> here... +!!end + +!! test +Edit comment with bare anchor link (local, as on diff) +!! options +comment +local +title=[[Main Page]] +!!input +[[#section]] +!! result +<a href="#section">#section</a> +!! end + +!! test +Edit comment with bare anchor link (non-local, as on history) +!! options +comment +title=[[Main Page]] +!!input +[[#section]] +!! result +<a href="/wiki/Main_Page#section" title="Main Page">#section</a> +!! end + +!! test +Anchor starting with underscore +!!input +[[#_ref|One]] +!! result +<p><a href="#_ref">One</a> +</p> +!! end + +!! test +Id starting with underscore +!!input +<div id="_ref"></div> +!! result +<div id="_ref"></div> + +!! end + +!! test +Space normalisation on autocomment (bug 22784) +!! options +comment +title=[[Main Page]] +!!input +/* __hello__world__ */ +!! result +<a href="/wiki/Main_Page#hello_world" title="Main Page">→</a><span dir="auto"><span class="autocomment">__hello__world__</span></span> +!! end + +!! test +percent-encoding and + signs in comments (Bug 26410) +!! options +comment +!!input +[[ABC%33D% ++]] [[ABC%33D% ++|+%20]] +!! result +<a href="/index.php?title=ABC3D%25_%2B%2B&action=edit&redlink=1" class="new" title="ABC3D% ++ (page does not exist)">ABC3D% ++</a> <a href="/index.php?title=ABC3D%25_%2B%2B&action=edit&redlink=1" class="new" title="ABC3D% ++ (page does not exist)">+%20</a> +!! end + +!! test +Bad images - basic functionality +!! options +disabled +!! input +[[File:Bad.jpg]] +!! result +!! end + +!! test +Bad images - bug 16039: text after bad image disappears +!! options +disabled +!! input +Foo bar +[[File:Bad.jpg]] +Bar foo +!! result +<p>Foo bar +</p><p>Bar foo +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) no displaytitle +!! options +showtitle +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=false +!! input +this is not the the title +!! result +Parser test +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) RestrictDisplayTitle=false +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=false +!! input +this is not the the title +{{DISPLAYTITLE:whatever}} +!! result +whatever +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) RestrictDisplayTitle=true mismatch +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:whatever}} +!! result +Screen +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) RestrictDisplayTitle=true matching +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=true +wgRestrictDisplayTitle=true +!! input +this is not the the title +{{DISPLAYTITLE:screen}} +!! result +screen +<p>this is not the the title +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) AllowDisplayTitle=false +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=false +!! input +this is not the the title +{{DISPLAYTITLE:screen}} +!! result +Screen +<p>this is not the the title +<a href="/index.php?title=Template:DISPLAYTITLE:screen&action=edit&redlink=1" class="new" title="Template:DISPLAYTITLE:screen (page does not exist)">Template:DISPLAYTITLE:screen</a> +</p> +!! end + +!! test +Verify that displaytitle works (bug #22501) AllowDisplayTitle=false no DISPLAYTITLE +!! options +showtitle +title=[[Screen]] +!! config +wgAllowDisplayTitle=false +!! input +this is not the the title +!! result +Screen +<p>this is not the the title +</p> +!! 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 +!! input +Hello <noinclude>cruel</noinclude><includeonly>kind</includeonly> world. +!! result +Hello kind world. +!! end + +!! test +preload: check <onlyinclude> +!! options +preload +!! input +Goodbye <onlyinclude>Hello world</onlyinclude> +!! result +Hello world +!! end + +!! test +preload: can pass tags through if we want to +!! options +preload +!! input +<includeonly><</includeonly>includeonly>Hello world<includeonly><</includeonly>/includeonly> +!! result +<includeonly>Hello world</includeonly> +!! end + +!! test +preload: check that it doesn't try to do tricks +!! options +preload +!! input +* <!-- Hello --> ''{{world}}'' {{<includeonly>subst:</includeonly>How are you}}{{ {{{|safesubst:}}} #if:1|2|3}} +!! result +* <!-- Hello --> ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}} +!! end + +!! test +Play a bit with r67090 and bug 3158 +!! options +disabled +!! input +<div style="width:50% !important"> </div> +<div style="width:50% !important"> </div> +<div style="width:50% !important"> </div> +<div style="border : solid;"> </div> +!! result +<div style="width:50% !important"> </div> +<div style="width:50% !important"> </div> +<div style="width:50% !important"> </div> +<div style="border : solid;"> </div> + +!! end + +!! test +HTML5 data attributes +!! input +<span data-foo="bar">Baz</span> +<p data-abc-def_hij="">Quuz</p> +!! result +<p><span data-foo="bar">Baz</span> +</p> +<p data-abc-def_hij="">Quuz</p> + +!! end + +!! test +percent-encoding and + signs in internal links (Bug 26410) +!! input +[[User:+%]] [[Page+title%]] +[[%+]] [[%+|%20]] [[%+ ]] [[%+r]] +[[%]] [[+]] [[image:%+abc%39|foo|[[bar]]]] +[[%33%45]] [[%33%45+]] +!! result +<p><a href="/index.php?title=User:%2B%25&action=edit&redlink=1" class="new" title="User:+% (page does not exist)">User:+%</a> <a href="/index.php?title=Page%2Btitle%25&action=edit&redlink=1" class="new" title="Page+title% (page does not exist)">Page+title%</a> +<a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%+</a> <a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%20</a> <a href="/index.php?title=%25%2B&action=edit&redlink=1" class="new" title="%+ (page does not exist)">%+ </a> <a href="/index.php?title=%25%2Br&action=edit&redlink=1" class="new" title="%+r (page does not exist)">%+r</a> +<a href="/index.php?title=%25&action=edit&redlink=1" class="new" title="% (page does not exist)">%</a> <a href="/index.php?title=%2B&action=edit&redlink=1" class="new" title="+ (page does not exist)">+</a> <a href="/index.php?title=Special:Upload&wpDestFile=%25%2Babc9" class="new" title="File:%+abc9">bar</a> +<a href="/index.php?title=3E&action=edit&redlink=1" class="new" title="3E (page does not exist)">3E</a> <a href="/index.php?title=3E%2B&action=edit&redlink=1" class="new" title="3E+ (page does not exist)">3E+</a> +</p> +!! end + +!! test +Special characters in embedded file links (bug 27679) +!! input +[[File:Contains & ampersand.jpg]] +[[File:Does not exist.jpg|Title with & ampersand]] +!! result +<p><a href="/index.php?title=Special:Upload&wpDestFile=Contains_%26_ampersand.jpg" class="new" title="File:Contains & ampersand.jpg">File:Contains & ampersand.jpg</a> +<a href="/index.php?title=Special:Upload&wpDestFile=Does_not_exist.jpg" class="new" title="File:Does not exist.jpg">Title with & ampersand</a> +</p> +!! end + + +!! test +Confirm that 'apos' named character reference doesn't make it to output (not legal in HTML 4) +!! input +Text's been normalized? +!! result +<p>Text's been normalized? +</p> +!! end + +!! test +Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate free external links +!! input +http://www.example.org/ <-- U+3000 (vim: ^Vu3000) +!! result +<p><a rel="nofollow" class="external free" href="http://www.example.org/">http://www.example.org/</a> <-- U+3000 (vim: ^Vu3000) +</p> +!! end + +!! test +Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate bracketed external links +!! input +[http://www.example.org/ ideograms] +!! result +<p><a rel="nofollow" class="external text" href="http://www.example.org/">ideograms</a> +</p> +!! end + +!! test +Bug 19052 U+3000 IDEOGRAPHIC SPACE should terminate external images links +!! input +http://www.example.org/pic.png <-- U+3000 (vim: ^Vu3000) +!! result +<p><img src="http://www.example.org/pic.png" alt="pic.png" /> <-- U+3000 (vim: ^Vu3000) +</p> +!! end + +!! article +Mediawiki:loop1 +!! text +{{Identical|A}} +!! endarticle + +!! article +Mediawiki:loop2 +!! text +{{Identical|B}} +!! endarticle + +!! article +Template:Identical +!! text +{{int:loop1}} +{{int:loop2}} +!! endarticle + +!! test +Bug 31098 Template which includes system messages which includes the template +!! input +{{Identical}} +!! result +<p><span class="error">Template loop detected: <a href="/wiki/Template:Identical" title="Template:Identical">Template:Identical</a></span> +<span class="error">Template loop detected: <a href="/wiki/Template:Identical" title="Template:Identical">Template:Identical</a></span> +</p> +!! end + +!! test +Bug31490 Turkish: ucfirst 'blah' +!! options +language=tr +!! input +{{ucfirst:blah}} +!! result +<p>Blah +</p> +!! end + +!! test +Bug31490 Turkish: ucfirst 'ix' +!! options +language=tr +!! input +{{ucfirst:ix}} +!! result +<p>İx +</p> +!! end + +!! test +Bug31490 Turkish: lcfirst 'BLAH' +!! options +language=tr +!! input +{{lcfirst:BLAH}} +!! result +<p>bLAH +</p> +!! end + +!! test +Bug31490 Turkish: ucfırst (with a dotless i) +!! options +language=tr +!! input +{{ucfırst:blah}} +!! result +<p><a href="/index.php?title=%C5%9Eablon:Ucf%C4%B1rst:blah&action=edit&redlink=1" class="new" title="Şablon:Ucfırst:blah (sayfa mevcut değil)">Şablon:Ucfırst:blah</a> +</p> +!! end + +!! test +Bug31490 ucfırst (with a dotless i) with English language +!! options +language=en +!! input +{{ucfırst:blah}} +!! result +<p><a href="/index.php?title=Template:Ucf%C4%B1rst:blah&action=edit&redlink=1" class="new" title="Template:Ucfırst:blah (page does not exist)">Template:Ucfırst:blah</a> +</p> +!! end + +!! test +Bug 26375: TOC with italics +!! options +title=[[Main Page]] +!! input +__TOC__ +== ''Lost'' episodes == +!! result +<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> +</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 + +!! test +Bug 26375: TOC with bold +!! options +title=[[Main Page]] +!! input +__TOC__ +== '''should be bold''' then normal text == +!! result +<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> +</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 + +!! test +Bug 33845: Headings become cursive in TOC when they contain an image +!! options +title=[[Main Page]] +!! input +__TOC__ +== Image [[Image:foobar.jpg]] == +!! result +<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> +</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 + +!! test +Bug 33845 (2): Headings become bold in TOC when they contain a blockquote +!! options +title=[[Main Page]] +!! input +__TOC__ +== <blockquote>Quote</blockquote> == +!! result +<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> +</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 + +!! test +Unclosed tags in TOC +!! options +title=[[Main Page]] +!! input +__TOC__ +== Proof: 2 < 3 == +<small>Hanc marginis exiguitas non caperet.</small> +QED +!! result +<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> +</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> +!! end + +!! test +Multiple tags in TOC +!! input +__TOC__ +== <i>Foo</i> <b>Bar</b> == + +== <i>Foo</i> <blockquote>Bar</blockquote> == +!! result +<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> +</div> < |