* Moved test record stuff to testHelpers.inc, could be useful for non-parser test stuff?
* Everything else in tests/parser
* parserTestsParserTime from r12533 doesn't seem used?
'LanguageConverter' => 'languages/LanguageConverter.php',
# maintenance
- 'AnsiTermColorer' => 'maintenance/parserTests.inc',
+ 'AnsiTermColorer' => 'maintenance/tests/testHelpers.inc',
'ConvertLinks' => 'maintenance/convertLinks.php',
- 'DbTestPreviewer' => 'maintenance/parserTests.inc',
- 'DbTestRecorder' => 'maintenance/parserTests.inc',
+ 'DbTestPreviewer' => 'maintenance/tests/testHelpers.inc',
+ 'DbTestRecorder' => 'maintenance/tests/testHelpers.inc',
'DeleteArchivedFilesImplementation' => 'maintenance/deleteArchivedFiles.inc',
'DeleteArchivedRevisionsImplementation' => 'maintenance/deleteArchivedRevisions.inc',
'DeleteDefaultMessages' => 'maintenance/deleteDefaultMessages.php',
- 'DummyTermColorer' => 'maintenance/parserTests.inc',
- 'ParserTest' => 'maintenance/parserTests.inc',
- 'ParserTestParserHook' => 'maintenance/parserTestsParserHook.php',
- 'ParserTestStaticParserHook' => 'maintenance/parserTestsStaticParserHook.php',
+ 'DummyTermColorer' => 'maintenance/tests/testHelpers.inc',
+ 'ParserTest' => 'maintenance/tests/parser/parserTest.inc',
+ 'ParserTestParserHook' => 'maintenance/tests/parser/parserTestsParserHook.php',
+ 'ParserTestStaticParserHook' => 'maintenance/tests/parser/parserTestsStaticParserHook.php',
'PopulateCategory' => 'maintenance/populateCategory.php',
'PopulateLogSearch' => 'maintenance/populateLogSearch.php',
'PopulateParentId' => 'maintenance/populateParentId.php',
'PopulateRevisionLength' => 'maintenance/populateRevisionLength.php',
- 'RemoteTestRecorder' => 'maintenance/parserTests.inc',
+ 'RemoteTestRecorder' => 'maintenance/tests/testHelpers.inc',
'SevenZipStream' => 'maintenance/7zip.inc',
'Sqlite' => 'maintenance/sqlite.inc',
- 'TestFileIterator' => 'maintenance/parserTests.inc',
- 'TestRecorder' => 'maintenance/parserTests.inc',
+ 'TestFileIterator' => 'maintenance/tests/testHelpers.inc',
+ 'TestRecorder' => 'maintenance/tests/testHelpers.inc',
'UpdateCollation' => 'maintenance/updateCollation.php',
'UpdateRestrictions' => 'maintenance/updateRestrictions.php',
'UserDupes' => 'maintenance/userDupes.inc',
* Use full paths.
*/
$wgParserTestFiles = array(
- "$IP/maintenance/parserTests.txt",
- "$IP/maintenance/ExtraParserTests.txt"
+ "$IP/maintenance/tests/parser/parserTests.txt",
+ "$IP/maintenance/tests/parser/ExtraParserTests.txt"
);
/**
@echo "Run 'make doc' to run the doxygen generation."
test:
- php parserTests.php --quiet
+ php tests/parserTests.php --quiet
doc:
php mwdocgen.php --all
+++ /dev/null
-<?php
-# Copyright (C) 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 Maintenance
- */
-
-/**
- * @ingroup Maintenance
- */
-class ParserTest {
- /**
- * boolean $color whereas output should be colorized
- */
- private $color;
-
- /**
- * boolean $showOutput Show test output
- */
- private $showOutput;
-
- /**
- * boolean $useTemporaryTables Use temporary tables for the temporary database
- */
- private $useTemporaryTables = true;
-
- /**
- * boolean $databaseSetupDone True if the database has been set up
- */
- private $databaseSetupDone = false;
-
- /**
- * string $oldTablePrefix Original table prefix
- */
- private $oldTablePrefix;
-
- private $maxFuzzTestLength = 300;
- private $fuzzSeed = 0;
- private $memoryLimit = 50;
-
- /**
- * Sets terminal colorization and diff/quick modes depending on OS and
- * command-line options (--color and --quick).
- */
- public function ParserTest( $options = array() ) {
- # Only colorize output if stdout is a terminal.
- $this->color = !wfIsWindows() && 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['regex'] ) ) {
- if ( isset( $options['record'] ) ) {
- echo "Warning: --record cannot be used with --regex, disabling --record\n";
- unset( $options['record'] );
- }
- $this->regex = $options['regex'];
- } else {
- # Matches anything
- $this->regex = '';
- }
-
- $this->setupRecorder( $options );
- $this->keepUploads = isset( $options['keep-uploads'] );
-
- if ( isset( $options['seed'] ) ) {
- $this->fuzzSeed = intval( $options['seed'] ) - 1;
- }
-
- $this->runDisabled = isset( $options['run-disabled'] );
-
- $this->hooks = array();
- $this->functionHooks = array();
- }
-
- 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 );
- } elseif ( isset( $options['upload'] ) ) {
- $this->recorder = new RemoteTestRecorder( $this );
- } else {
- $this->recorder = new TestRecorder( $this );
- }
- }
-
- /**
- * Remove last character if it is a newline
- */
- public function chomp( $s ) {
- if ( substr( $s, -1 ) === "\n" ) {
- return substr( $s, 0, -1 );
- }
- else {
- return $s;
- }
- }
-
- /**
- * Run a fuzz test series
- * Draw input from a set of test files
- */
- function fuzzTest( $filenames ) {
- $GLOBALS['wgContLang'] = Language::factory( 'en' );
- $dict = $this->getFuzzInput( $filenames );
- $dictSize = strlen( $dict );
- $logMaxLength = log( $this->maxFuzzTestLength );
- $this->setupDatabase();
- ini_set( 'memory_limit', $this->memoryLimit * 1048576 );
-
- $numTotal = 0;
- $numSuccess = 0;
- $user = new User;
- $opts = ParserOptions::newFromUser( $user );
- $title = Title::makeTitle( NS_MAIN, 'Parser_test' );
-
- while ( true ) {
- // Generate test input
- mt_srand( ++$this->fuzzSeed );
- $totalLength = mt_rand( 1, $this->maxFuzzTestLength );
- $input = '';
-
- while ( strlen( $input ) < $totalLength ) {
- $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength;
- $hairLength = min( intval( exp( $logHairLength ) ), $dictSize );
- $offset = mt_rand( 0, $dictSize - $hairLength );
- $input .= substr( $dict, $offset, $hairLength );
- }
-
- $this->setupGlobals();
- $parser = $this->getParser();
-
- // Run the test
- try {
- $parser->parse( $input, $title, $opts );
- $fail = false;
- } catch ( Exception $exception ) {
- $fail = true;
- }
-
- if ( $fail ) {
- echo "Test failed with seed {$this->fuzzSeed}\n";
- echo "Input:\n";
- var_dump( $input );
- echo "\n\n";
- 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 ) {
- $GLOBALS['wgContLang'] = Language::factory( 'en' );
- $this->recorder->start();
- $this->setupDatabase();
- $ok = true;
-
- foreach ( $filenames as $filename ) {
- $tests = new TestFileIterator( $filename, $this );
- $ok = $this->runTests( $tests ) && $ok;
- }
-
- $this->teardownDatabase();
- $this->recorder->report();
- $this->recorder->end();
-
- return $ok;
- }
-
- function runTests( $tests ) {
- $ok = true;
-
- foreach ( $tests as $i => $t ) {
- $result =
- $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] );
- $ok = $ok && $result;
- $this->recorder->record( $t['test'], $result );
- }
-
- if ( $this->showProgress ) {
- print "\n";
- }
-
- return $ok;
- }
-
- /**
- * Get a Parser object
- */
- function getParser( $preprocessor = null ) {
- global $wgParserConf;
-
- $class = $wgParserConf['class'];
- $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf );
-
- foreach ( $this->hooks as $tag => $callback ) {
- $parser->setHook( $tag, $callback );
- }
-
- foreach ( $this->functionHooks as $tag => $bits ) {
- list( $callback, $flags ) = $bits;
- $parser->setFunctionHook( $tag, $callback, $flags );
- }
-
- wfRunHooks( 'ParserTestParser', array( &$parser ) );
-
- return $parser;
- }
-
- /**
- * Run a given wikitext input through a freshly-constructed wiki parser,
- * and compare the output against the expected results.
- * Prints status and explanatory messages to stdout.
- *
- * @param $desc String: test's description
- * @param $input String: wikitext to try rendering
- * @param $result String: result to output
- * @param $opts Array: test's options
- * @param $config String: overrides for global variables, one per line
- * @return Boolean
- */
- public function runTest( $desc, $input, $result, $opts, $config ) {
- if ( $this->showProgress ) {
- $this->showTesting( $desc );
- }
-
- $opts = $this->parseOptions( $opts );
- $this->setupGlobals( $opts, $config );
-
- $user = new User();
- $options = ParserOptions::newFromUser( $user );
-
- if ( isset( $opts['title'] ) ) {
- $titleText = $opts['title'];
- }
- else {
- $titleText = 'Parser test';
- }
-
- $noxml = isset( $opts['noxml'] );
- $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 );
- } 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'] ) ) {
- $linker = $user->getSkin();
- $out = $linker->formatComment( $input, $title, $local );
- } elseif ( isset( $opts['preload'] ) ) {
- $out = $parser->getpreloadText( $input, $title, $options );
- } else {
- $output = $parser->parse( $input, $title, $options, true, true, 1337 );
- $out = $output->getText();
-
- if ( isset( $opts['showtitle'] ) ) {
- if ( $output->getTitleText() ) {
- $title = $output->getTitleText();
- }
-
- $out = "$title\n$out";
- }
-
- if ( isset( $opts['ill'] ) ) {
- $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
- } elseif ( isset( $opts['cat'] ) ) {
- global $wgOut;
-
- $wgOut->addCategoryLinks( $output->getCategories() );
- $cats = $wgOut->getCategoryLinks();
-
- if ( isset( $cats['normal'] ) ) {
- $out = $this->tidy( implode( ' ', $cats['normal'] ) );
- } else {
- $out = '';
- }
- }
-
- $result = $this->tidy( $result );
- }
-
-
- $this->teardownGlobals();
-
- if ( $result === $out && ( $noxml === true || $this->wellFormed( $out ) ) ) {
- return $this->showSuccess( $desc );
- } else {
- return $this->showFailure( $desc, $result, $out );
- }
- }
-
- /**
- * Use a regex to find out the value of an option
- * @param $key String: name of option val to retrieve
- * @param $opts Options array to look in
- * @param $default Mixed: default value returned if not found
- */
- private static function getOptionValue( $key, $opts, $default ) {
- $key = strtolower( $key );
-
- if ( isset( $opts[$key] ) ) {
- return $opts[$key];
- } else {
- return $default;
- }
- }
-
- private function parseOptions( $instring ) {
- $opts = array();
- $lines = explode( "\n", $instring );
- // 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 ) {
- $match = 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 = '' ) {
- global $wgDBtype;
-
- # 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://localhost',
- 'wgScript' => '/index.php',
- 'wgScriptPath' => '/',
- 'wgArticlePath' => '/wiki/$1',
- 'wgActionPaths' => array(),
- 'wgLocalFileRepo' => array(
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'directory' => $this->uploadDir,
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
- 'transformVia404' => false,
- ),
- 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
- 'wgStyleSheetPath' => '/skins',
- 'wgSitename' => 'MediaWiki',
- 'wgServerName' => 'Britney-Spears',
- 'wgLanguageCode' => $lang,
- 'wgDBprefix' => $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_',
- 'wgRawHtml' => isset( $opts['rawhtml'] ),
- 'wgLang' => null,
- 'wgContLang' => null,
- 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ),
- 'wgMaxTocLevel' => $maxtoclevel,
- 'wgCapitalLinks' => true,
- 'wgNoFollowLinks' => true,
- 'wgNoFollowDomainExceptions' => array(),
- 'wgThumbnailScriptPath' => false,
- 'wgUseImageResize' => false,
- 'wgUseTeX' => isset( $opts['math'] ),
- 'wgMathDirectory' => $this->uploadDir . '/math',
- 'wgLocaltimezone' => 'UTC',
- 'wgAllowExternalImages' => true,
- 'wgUseTidy' => false,
- 'wgDefaultLanguageVariant' => $variant,
- 'wgVariantArticlePath' => false,
- 'wgGroupPermissions' => array( '*' => array(
- 'createaccount' => true,
- 'read' => true,
- 'edit' => true,
- 'createpage' => true,
- 'createtalk' => true,
- ) ),
- 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
- 'wgDefaultExternalStore' => array(),
- 'wgForeignFileRepos' => array(),
- 'wgLinkHolderBatchSize' => $linkHolderBatchSize,
- 'wgExperimentalHtmlIds' => false,
- 'wgExternalLinkTarget' => false,
- 'wgAlwaysUseTidy' => false,
- 'wgHtml5' => true,
- 'wgWellFormedXml' => true,
- 'wgAllowMicrodataAttributes' => true,
- );
-
- if ( $config ) {
- $configLines = explode( "\n", $config );
-
- foreach ( $configLines as $line ) {
- list( $var, $value ) = explode( '=', $line, 2 );
-
- $settings[$var] = eval( "return $value;" );
- }
- }
-
- $this->savedGlobals = array();
-
- foreach ( $settings as $var => $val ) {
- if ( array_key_exists( $var, $GLOBALS ) ) {
- $this->savedGlobals[$var] = $GLOBALS[$var];
- }
-
- $GLOBALS[$var] = $val;
- }
-
- $langObj = Language::factory( $lang );
- $GLOBALS['wgLang'] = $langObj;
- $GLOBALS['wgContLang'] = $langObj;
- $GLOBALS['wgMemc'] = new FakeMemCachedClient;
- $GLOBALS['wgOut'] = new OutputPage;
-
- global $wgHooks;
-
- $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
- $wgHooks['ParserTestParser'][] = 'ParserTestStaticParserHook::setup';
- $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
-
- MagicWord::clearCache();
-
- global $wgUser;
- $wgUser = new User();
- }
-
- /**
- * List of temporary tables to create, without prefix.
- * Some of these probably aren't necessary.
- */
- private function listTables() {
- global $wgDBtype;
-
- $tables = array( 'user', 'user_properties', 'page', 'page_restrictions',
- 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
- 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
- 'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage',
- 'recentchanges', 'watchlist', 'math', 'interwiki', 'logging',
- 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
- 'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links'
- );
-
- if ( in_array( $wgDBtype, array( 'mysql', 'sqlite' ) ) )
- 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, $wgDBtype;
-
- if ( $this->databaseSetupDone ) {
- return;
- }
-
- if ( $wgDBprefix === 'parsertest_' || ( $wgDBtype == '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?).
- # If it fails, $wgCaches[CACHE_DB] = new HashBagOStuff(); should work around it.
-
- # CREATE TEMPORARY TABLE breaks if there is more than one server
- if ( wfGetLB()->getServerCount() != 1 ) {
- $this->useTemporaryTables = false;
- }
-
- $temporary = $this->useTemporaryTables || $wgDBtype == 'postgres';
-
- $db = wfGetDB( DB_MASTER );
- $tables = $this->listTables();
-
- foreach ( $tables as $tbl ) {
- # Clean up from previous aborted run. So that table escaping
- # works correctly across DB engines, we need to change the pre-
- # fix back and forth so tableName() works right.
- $this->changePrefix( $this->oldTablePrefix );
- $oldTableName = $db->tableName( $tbl );
- $this->changePrefix( $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_' );
- $newTableName = $db->tableName( $tbl );
-
- if ( $wgDBtype == 'mysql' ) {
- $db->query( "DROP TABLE IF EXISTS $newTableName" );
- } elseif ( in_array( $wgDBtype, array( 'postgres', 'oracle' ) ) ) {
- /* DROPs wouldn't work due to Foreign Key Constraints (bug 14990, r58669)
- * Use "DROP TABLE IF EXISTS $newTableName CASCADE" for postgres? That
- * syntax would also work for mysql.
- */
- } elseif ( $db->tableExists( $tbl ) ) {
- $db->query( "DROP TABLE $newTableName" );
- }
-
- # Create new table
- $db->duplicateTableStructure( $oldTableName, $newTableName, $temporary );
- }
-
- if ( $wgDBtype == 'oracle' )
- $db->query( 'BEGIN FILL_WIKI_INFO; END;' );
-
- $this->changePrefix( $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_' );
-
- # Hack: insert a few Wikipedia in-project interwiki prefixes,
- # for testing inter-language links
- $db->insert( 'interwiki', array(
- array( 'iw_prefix' => 'wikipedia',
- 'iw_url' => 'http://en.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ),
- array( 'iw_prefix' => 'meatball',
- 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 0 ),
- array( 'iw_prefix' => 'zh',
- 'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ),
- array( 'iw_prefix' => 'es',
- 'iw_url' => 'http://es.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ),
- array( 'iw_prefix' => 'fr',
- 'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ),
- array( 'iw_prefix' => 'ru',
- 'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
- 'iw_api' => '',
- 'iw_wikiid' => '',
- 'iw_local' => 1 ),
- ) );
-
-
- if ( $wgDBtype == 'oracle' ) {
- # Insert 0 user to prevent FK violations
-
- # Anonymous user
- $db->insert( 'user', array(
- 'user_id' => 0,
- 'user_name' => 'Anonymous' ) );
- }
-
- # Update certain things in site_stats
- $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();
-
- # Make a new message cache
- global $wgMessageCache, $wgMemc;
- $wgMessageCache = new MessageCache( $wgMemc, true, 3600 );
-
- $this->uploadDir = $this->setupUploadDir();
- $user = User::createNew( 'WikiSysop' );
- $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
- $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array(
- 'size' => 12345,
- 'width' => 1941,
- 'height' => 220,
- 'bits' => 24,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( array() ),
- 'sha1' => sha1( '' ),
- 'fileExists' => true
- ), $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' => sha1( '' ),
- 'fileExists' => true
- ), $db->timestamp( '20010115123500' ), $user );
- }
-
- /**
- * Change the table prefix on all open DB connections/
- */
- protected function changePrefix( $prefix ) {
- global $wgDBprefix;
- wfGetLBFactory()->forEachLB( array( $this, 'changeLBPrefix' ), array( $prefix ) );
- $wgDBprefix = $prefix;
- }
-
- public function changeLBPrefix( $lb, $prefix ) {
- $lb->forEachOpenConnection( array( $this, 'changeDBPrefix' ), array( $prefix ) );
- }
-
- public function changeDBPrefix( $db, $prefix ) {
- $db->tablePrefix( $prefix );
- }
-
- public function teardownDatabase() {
- global $wgDBtype;
-
- if ( !$this->databaseSetupDone ) {
- return;
- }
- $this->teardownUploadDir( $this->uploadDir );
-
- $this->changePrefix( $this->oldTablePrefix );
- $this->databaseSetupDone = false;
-
- if ( $this->useTemporaryTables ) {
- # Don't need to do anything
- return;
- }
-
- $tables = $this->listTables();
- $db = wfGetDB( DB_MASTER );
-
- foreach ( $tables as $table ) {
- $sql = $wgDBtype == 'oracle' ? "DROP TABLE pt_$table DROP CONSTRAINTS" : "DROP TABLE `parsertest_$table`";
- $db->query( $sql );
- }
-
- if ( $wgDBtype == 'oracle' )
- $db->query( 'BEGIN FILL_WIKI_INFO; END;' );
- }
-
- /**
- * 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' );
- copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" );
- wfMkdirParents( $dir . '/0/09' );
- copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" );
-
- return $dir;
- }
-
- /**
- * Restore default values and perform any necessary clean-up
- * after each test runs.
- */
- private function teardownGlobals() {
- RepoGroup::destroySingleton();
- LinkCache::singleton()->clear();
-
- foreach ( $this->savedGlobals as $var => $val ) {
- $GLOBALS[$var] = $val;
- }
- }
-
- /**
- * Remove the dummy uploads directory
- */
- private function teardownUploadDir( $dir ) {
- if ( $this->keepUploads ) {
- return;
- }
-
- // delete the files first, then the dirs.
- self::deleteFiles(
- array (
- "$dir/3/3a/Foobar.jpg",
- "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
- "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
- "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
- "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
-
- "$dir/0/09/Bad.jpg",
-
- "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
- )
- );
-
- self::deleteDirs(
- array (
- "$dir/3/3a",
- "$dir/3",
- "$dir/thumb/6/65",
- "$dir/thumb/6",
- "$dir/thumb/3/3a/Foobar.jpg",
- "$dir/thumb/3/3a",
- "$dir/thumb/3",
-
- "$dir/0/09/",
- "$dir/0/",
- "$dir/thumb",
- "$dir/math/f/a/5",
- "$dir/math/f/a",
- "$dir/math/f",
- "$dir/math",
- "$dir",
- )
- );
- }
-
- /**
- * Delete the specified files, if they exist.
- * @param $files Array: full paths to files to delete.
- */
- private static function deleteFiles( $files ) {
- foreach ( $files as $file ) {
- if ( file_exists( $file ) ) {
- unlink( $file );
- }
- }
- }
-
- /**
- * Delete the specified directories, if they exist. Must be empty.
- * @param $dirs Array: full paths to directories to delete.
- */
- private static function deleteDirs( $dirs ) {
- foreach ( $dirs as $dir ) {
- if ( is_dir( $dir ) ) {
- rmdir( $dir );
- }
- }
- }
-
- /**
- * "Running test $desc..."
- */
- protected function showTesting( $desc ) {
- print "Running test $desc... ";
- }
-
- /**
- * Print a happy success message.
- *
- * @param $desc String: the test name
- * @return Boolean
- */
- protected function showSuccess( $desc ) {
- if ( $this->showProgress ) {
- print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
- }
-
- return true;
- }
-
- /**
- * Print a failure message and provide some explanatory output
- * about what went wrong if so configured.
- *
- * @param $desc String: the test name
- * @param $result String: expected HTML output
- * @param $html String: actual HTML output
- * @return Boolean
- */
- protected function showFailure( $desc, $result, $html ) {
- if ( $this->showFailure ) {
- if ( !$this->showProgress ) {
- # In quiet mode we didn't show the 'Testing' message before the
- # test, in case it succeeded. Show it now:
- $this->showTesting( $desc );
- }
-
- print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n";
-
- if ( $this->showOutput ) {
- print "--- Expected ---\n$result\n--- Actual ---\n$html\n";
- }
-
- if ( $this->showDiffs ) {
- print $this->quickDiff( $result, $html );
- if ( !$this->wellFormed( $html ) ) {
- print "XML error: $this->mXmlError\n";
- }
- }
- }
-
- return false;
- }
-
- /**
- * Run given strings through a diff and return the (colorized) output.
- * Requires writable /tmp directory and a 'diff' command in the PATH.
- *
- * @param $input String
- * @param $output String
- * @param $inFileTail String: tailing for the input file name
- * @param $outFileTail String: tailing for the output file name
- * @return String
- */
- protected function quickDiff( $input, $output, $inFileTail = 'expected', $outFileTail = 'actual' ) {
- $prefix = wfTempDir() . "/mwParser-" . mt_rand();
-
- $infile = "$prefix-$inFileTail";
- $this->dumpToFile( $input, $infile );
-
- $outfile = "$prefix-$outFileTail";
- $this->dumpToFile( $output, $outfile );
-
- $diff = `diff -au $infile $outfile`;
- 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
- */
- public function addArticle( $name, $text, $line ) {
- global $wgCapitalLinks;
- $oldCapitalLinks = $wgCapitalLinks;
- $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637
-
- $title = Title::newFromText( $name );
-
- if ( is_null( $title ) ) {
- wfDie( "invalid title at line $line\n" );
- }
-
- $aid = $title->getArticleID( GAID_FOR_UPDATE );
-
- if ( $aid != 0 ) {
- wfDie( "duplicate article '$name' at line $line\n" );
- }
-
- $art = new Article( $title );
- $art->insertNewArticle( $text, '', false, false );
-
- $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
- * @static
- */
- 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;
- return true;
- }
-}
-
-class AnsiTermColorer {
- function __construct() {
- }
-
- /**
- * Return ANSI terminal escape code for changing text attribs/color
- *
- * @param $color String: semicolon-separated list of attribute/color codes
- * @return String
- */
- public function color( $color ) {
- global $wgCommandLineDarkBg;
-
- $light = $wgCommandLineDarkBg ? "1;" : "0;";
-
- return "\x1b[{$light}{$color}m";
- }
-
- /**
- * Return ANSI terminal escape code for restoring default text attributes
- *
- * @return String
- */
- public function reset() {
- return $this->color( 0 );
- }
-}
-
-/* A colour-less terminal */
-class DummyTermColorer {
- public function color( $color ) {
- return '';
- }
-
- public function reset() {
- return '';
- }
-}
-
-class TestRecorder {
- var $parent;
- var $term;
-
- function __construct( $parent ) {
- $this->parent = $parent;
- $this->term = $parent->term;
- }
-
- function start() {
- $this->total = 0;
- $this->success = 0;
- }
-
- function record( $test, $result ) {
- $this->total++;
- $this->success += ( $result ? 1 : 0 );
- }
-
- function end() {
- // dummy
- }
-
- function report() {
- if ( $this->total > 0 ) {
- $this->reportPercentage( $this->success, $this->total );
- } else {
- wfDie( "No tests found.\n" );
- }
- }
-
- function reportPercentage( $success, $total ) {
- $ratio = wfPercent( 100 * $success / $total );
- print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)... ";
-
- if ( $success == $total ) {
- print $this->term->color( 32 ) . "ALL TESTS PASSED!";
- } else {
- $failed = $total - $success ;
- print $this->term->color( 31 ) . "$failed tests failed!";
- }
-
- print $this->term->reset() . "\n";
-
- return ( $success == $total );
- }
-}
-
-class DbTestPreviewer extends TestRecorder {
- protected $lb; // /< Database load balancer
- protected $db; // /< Database connection to the main DB
- protected $curRun; // /< run ID number for the current run
- protected $prevRun; // /< run ID number for the previous run, if any
- protected $results; // /< Result array
-
- /**
- * This should be called before the table prefix is changed
- */
- function __construct( $parent ) {
- parent::__construct( $parent );
-
- $this->lb = wfGetLBFactory()->newMainLB();
- // This connection will have the wiki's table prefix, not parsertest_
- $this->db = $this->lb->getConnection( DB_MASTER );
- }
-
- /**
- * Set up result recording; insert a record for the run with the date
- * and all that fun stuff
- */
- function start() {
- parent::start();
-
- if ( ! $this->db->tableExists( 'testrun' )
- or ! $this->db->tableExists( 'testitem' ) )
- {
- print "WARNING> `testrun` table not found in database.\n";
- $this->prevRun = false;
- } else {
- // We'll make comparisons against the previous run later...
- $this->prevRun = $this->db->selectField( 'testrun', 'MAX(tr_id)' );
- }
-
- $this->results = array();
- }
-
- function record( $test, $result ) {
- parent::record( $test, $result );
- $this->results[$test] = $result;
- }
-
- function report() {
- if ( $this->prevRun ) {
- // f = fail, p = pass, n = nonexistent
- // codes show before then after
- $table = array(
- 'fp' => 'previously failing test(s) now PASSING! :)',
- 'pn' => 'previously PASSING test(s) removed o_O',
- 'np' => 'new PASSING test(s) :)',
-
- 'pf' => 'previously passing test(s) now FAILING! :(',
- 'fn' => 'previously FAILING test(s) removed O_o',
- 'nf' => 'new FAILING test(s) :(',
- 'ff' => 'still FAILING test(s) :(',
- );
-
- $prevResults = array();
-
- $res = $this->db->select( 'testitem', array( 'ti_name', 'ti_success' ),
- array( 'ti_run' => $this->prevRun ), __METHOD__ );
-
- foreach ( $res as $row ) {
- if ( !$this->parent->regex
- || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) )
- {
- $prevResults[$row->ti_name] = $row->ti_success;
- }
- }
-
- $combined = array_keys( $this->results + $prevResults );
-
- # Determine breakdown by change type
- $breakdown = array();
- foreach ( $combined as $test ) {
- if ( !isset( $prevResults[$test] ) ) {
- $before = 'n';
- } elseif ( $prevResults[$test] == 1 ) {
- $before = 'p';
- } else /* if ( $prevResults[$test] == 0 )*/ {
- $before = 'f';
- }
-
- if ( !isset( $this->results[$test] ) ) {
- $after = 'n';
- } elseif ( $this->results[$test] == 1 ) {
- $after = 'p';
- } else /*if ( $this->results[$test] == 0 ) */ {
- $after = 'f';
- }
-
- $code = $before . $after;
-
- if ( isset( $table[$code] ) ) {
- $breakdown[$code][$test] = $this->getTestStatusInfo( $test, $after );
- }
- }
-
- # Write out results
- foreach ( $table as $code => $label ) {
- if ( !empty( $breakdown[$code] ) ) {
- $count = count( $breakdown[$code] );
- printf( "\n%4d %s\n", $count, $label );
-
- foreach ( $breakdown[$code] as $differing_test_name => $statusInfo ) {
- print " * $differing_test_name [$statusInfo]\n";
- }
- }
- }
- } else {
- print "No previous test runs to compare against.\n";
- }
-
- print "\n";
- parent::report();
- }
-
- /**
- * Returns a string giving information about when a test last had a status change.
- * Could help to track down when regressions were introduced, as distinct from tests
- * which have never passed (which are more change requests than regressions).
- */
- private function getTestStatusInfo( $testname, $after ) {
- // If we're looking at a test that has just been removed, then say when it first appeared.
- if ( $after == 'n' ) {
- $changedRun = $this->db->selectField ( 'testitem',
- 'MIN(ti_run)',
- array( 'ti_name' => $testname ),
- __METHOD__ );
- $appear = $this->db->selectRow ( 'testrun',
- array( 'tr_date', 'tr_mw_version' ),
- array( 'tr_id' => $changedRun ),
- __METHOD__ );
-
- return "First recorded appearance: "
- . date( "d-M-Y H:i:s", strtotime ( $appear->tr_date ) )
- . ", " . $appear->tr_mw_version;
- }
-
- // Otherwise, this test has previous recorded results.
- // See when this test last had a different result to what we're seeing now.
- $conds = array(
- 'ti_name' => $testname,
- 'ti_success' => ( $after == 'f' ? "1" : "0" ) );
-
- if ( $this->curRun ) {
- $conds[] = "ti_run != " . $this->db->addQuotes ( $this->curRun );
- }
-
- $changedRun = $this->db->selectField ( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
-
- // If no record of ever having had a different result.
- if ( is_null ( $changedRun ) ) {
- if ( $after == "f" ) {
- return "Has never passed";
- } else {
- return "Has never failed";
- }
- }
-
- // Otherwise, we're looking at a test whose status has changed.
- // (i.e. it used to work, but now doesn't; or used to fail, but is now fixed.)
- // In this situation, give as much info as we can as to when it changed status.
- $pre = $this->db->selectRow ( 'testrun',
- array( 'tr_date', 'tr_mw_version' ),
- array( 'tr_id' => $changedRun ),
- __METHOD__ );
- $post = $this->db->selectRow ( 'testrun',
- array( 'tr_date', 'tr_mw_version' ),
- array( "tr_id > " . $this->db->addQuotes ( $changedRun ) ),
- __METHOD__,
- array( "LIMIT" => 1, "ORDER BY" => 'tr_id' )
- );
-
- if ( $post ) {
- $postDate = date( "d-M-Y H:i:s", strtotime ( $post->tr_date ) ) . ", {$post->tr_mw_version}";
- } else {
- $postDate = 'now';
- }
-
- return ( $after == "f" ? "Introduced" : "Fixed" ) . " between "
- . date( "d-M-Y H:i:s", strtotime ( $pre->tr_date ) ) . ", " . $pre->tr_mw_version
- . " and $postDate";
-
- }
-
- /**
- * Commit transaction and clean up for result recording
- */
- function end() {
- $this->lb->commitMasterChanges();
- $this->lb->closeAll();
- parent::end();
- }
-
-}
-
-class DbTestRecorder extends DbTestPreviewer {
- var $version;
-
- /**
- * Set up result recording; insert a record for the run with the date
- * and all that fun stuff
- */
- function start() {
- global $wgDBtype;
- $this->db->begin();
-
- if ( ! $this->db->tableExists( 'testrun' )
- or ! $this->db->tableExists( 'testitem' ) )
- {
- print "WARNING> `testrun` table not found in database. Trying to create table.\n";
- if ( $wgDBtype === 'postgres' ) {
- $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.postgres.sql' );
- } elseif ( $wgDBtype === 'oracle' ) {
- $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.ora.sql' );
- } else {
- $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.sql' );
- }
-
- echo "OK, resuming.\n";
- }
-
- parent::start();
-
- $this->db->insert( 'testrun',
- array(
- 'tr_date' => $this->db->timestamp(),
- 'tr_mw_version' => $this->version,
- 'tr_php_version' => phpversion(),
- 'tr_db_version' => $this->db->getServerVersion(),
- 'tr_uname' => php_uname()
- ),
- __METHOD__ );
- if ( $wgDBtype === 'postgres' ) {
- $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
- } else {
- $this->curRun = $this->db->insertId();
- }
- }
-
- /**
- * Record an individual test item's success or failure to the db
- *
- * @param $test String
- * @param $result Boolean
- */
- function record( $test, $result ) {
- parent::record( $test, $result );
-
- $this->db->insert( 'testitem',
- array(
- 'ti_run' => $this->curRun,
- 'ti_name' => $test,
- 'ti_success' => $result ? 1 : 0,
- ),
- __METHOD__ );
- }
-}
-
-class RemoteTestRecorder extends TestRecorder {
- function start() {
- parent::start();
-
- $this->results = array();
- $this->ping( 'running' );
- }
-
- function record( $test, $result ) {
- parent::record( $test, $result );
- $this->results[$test] = (bool)$result;
- }
-
- function end() {
- $this->ping( 'complete', $this->results );
- parent::end();
- }
-
- /**
- * Inform a CodeReview instance that we've started or completed a test run...
- *
- * @param $status string: "running" - tell it we've started
- * "complete" - provide test results array
- * "abort" - something went horribly awry
- * @param $results array of test name => true/false
- */
- function ping( $status, $results = false ) {
- global $wgParserTestRemote, $IP;
-
- $remote = $wgParserTestRemote;
- $revId = SpecialVersion::getSvnRevision( $IP );
- $jsonResults = FormatJson::encode( $results );
-
- if ( !$remote ) {
- print "Can't do remote upload without configuring \$wgParserTestRemote!\n";
- exit( 1 );
- }
-
- // Generate a hash MAC to validate our credentials
- $message = array(
- $remote['repo'],
- $remote['suite'],
- $revId,
- $status,
- );
-
- if ( $status == "complete" ) {
- $message[] = $jsonResults;
- }
- $hmac = hash_hmac( "sha1", implode( "|", $message ), $remote['secret'] );
-
- $postData = array(
- 'action' => 'codetestupload',
- 'format' => 'json',
- 'repo' => $remote['repo'],
- 'suite' => $remote['suite'],
- 'rev' => $revId,
- 'status' => $status,
- 'hmac' => $hmac,
- );
-
- if ( $status == "complete" ) {
- $postData['results'] = $jsonResults;
- }
-
- $response = $this->post( $remote['api-url'], $postData );
-
- if ( $response === false ) {
- print "CodeReview info upload failed to reach server.\n";
- exit( 1 );
- }
-
- $responseData = FormatJson::decode( $response, true );
-
- if ( !is_array( $responseData ) ) {
- print "CodeReview API response not recognized...\n";
- wfDebug( "Unrecognized CodeReview API response: $response\n" );
- exit( 1 );
- }
-
- if ( isset( $responseData['error'] ) ) {
- $code = $responseData['error']['code'];
- $info = $responseData['error']['info'];
- print "CodeReview info upload failed: $code $info\n";
- exit( 1 );
- }
- }
-
- function post( $url, $data ) {
- return Http::post( $url, array( 'postData' => $data ) );
- }
-}
-
-class TestFileIterator implements Iterator {
- private $file;
- private $fh;
- private $parser;
- private $index = 0;
- private $test;
- private $lineNum;
- private $eof;
-
- function __construct( $file, $parser = null ) {
- global $IP;
-
- $this->file = $file;
- $this->fh = fopen( $this->file, "rt" );
-
- if ( !$this->fh ) {
- wfDie( "Couldn't open file '$file'\n" );
- }
-
- $this->parser = $parser;
-
- if ( $this->parser ) {
- $this->parser->showRunFile( wfRelativePath( $this->file, $IP ) );
- }
-
- $this->lineNum = $this->index = 0;
- }
-
- function setParser( ParserTest $parser ) {
- $this->parser = $parser;
- }
-
- function rewind() {
- if ( fseek( $this->fh, 0 ) ) {
- wfDie( "Couldn't fseek to the start of '$this->file'\n" );
- }
-
- $this->index = -1;
- $this->lineNum = 0;
- $this->eof = false;
- $this->next();
-
- return true;
- }
-
- function current() {
- return $this->test;
- }
-
- function key() {
- return $this->index;
- }
-
- function next() {
- if ( $this->readNextTest() ) {
- $this->index++;
- return true;
- } else {
- $this->eof = true;
- }
- }
-
- function valid() {
- return $this->eof != true;
- }
-
- function readNextTest() {
- $data = array();
- $section = null;
-
- while ( false !== ( $line = fgets( $this->fh ) ) ) {
- $this->lineNum++;
- $matches = array();
-
- if ( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
- $section = strtolower( $matches[1] );
-
- if ( $section == 'endarticle' ) {
- if ( !isset( $data['text'] ) ) {
- wfDie( "'endarticle' without 'text' at line {$this->lineNum} of $this->file\n" );
- }
-
- if ( !isset( $data['article'] ) ) {
- wfDie( "'endarticle' without 'article' at line {$this->lineNum} of $this->file\n" );
- }
-
- if ( $this->parser ) {
- $this->parser->addArticle( $this->parser->chomp( $data['article'] ), $this->parser->chomp( $data['text'] ),
- $this->lineNum );
- }
-
- $data = array();
- $section = null;
-
- continue;
- }
-
- if ( $section == 'endhooks' ) {
- if ( !isset( $data['hooks'] ) ) {
- wfDie( "'endhooks' without 'hooks' at line {$this->lineNum} of $this->file\n" );
- }
-
- foreach ( explode( "\n", $data['hooks'] ) as $line ) {
- $line = trim( $line );
-
- if ( $line ) {
- if ( $this->parser && !$this->parser->requireHook( $line ) ) {
- return false;
- }
- }
- }
-
- $data = array();
- $section = null;
-
- continue;
- }
-
- if ( $section == 'endfunctionhooks' ) {
- if ( !isset( $data['functionhooks'] ) ) {
- wfDie( "'endfunctionhooks' without 'functionhooks' at line {$this->lineNum} of $this->file\n" );
- }
-
- foreach ( explode( "\n", $data['functionhooks'] ) as $line ) {
- $line = trim( $line );
-
- if ( $line ) {
- if ( $this->parser && !$this->parser->requireFunctionHook( $line ) ) {
- return false;
- }
- }
- }
-
- $data = array();
- $section = null;
-
- continue;
- }
-
- if ( $section == 'end' ) {
- if ( !isset( $data['test'] ) ) {
- wfDie( "'end' without 'test' at line {$this->lineNum} of $this->file\n" );
- }
-
- if ( !isset( $data['input'] ) ) {
- wfDie( "'end' without 'input' at line {$this->lineNum} of $this->file\n" );
- }
-
- if ( !isset( $data['result'] ) ) {
- wfDie( "'end' without 'result' at line {$this->lineNum} of $this->file\n" );
- }
-
- if ( !isset( $data['options'] ) ) {
- $data['options'] = '';
- }
-
- if ( !isset( $data['config'] ) )
- $data['config'] = '';
-
- if ( $this->parser
- && ( ( preg_match( '/\\bdisabled\\b/i', $data['options'] ) && !$this->parser->runDisabled )
- || !preg_match( "/" . $this->parser->regex . "/i", $data['test'] ) ) ) {
- # disabled test
- $data = array();
- $section = null;
-
- continue;
- }
-
- global $wgUseTeX;
-
- if ( $this->parser &&
- preg_match( '/\\bmath\\b/i', $data['options'] ) && !$wgUseTeX ) {
- # don't run math tests if $wgUseTeX is set to false in LocalSettings
- $data = array();
- $section = null;
-
- continue;
- }
-
- if ( $this->parser ) {
- $this->test = array(
- 'test' => $this->parser->chomp( $data['test'] ),
- 'input' => $this->parser->chomp( $data['input'] ),
- 'result' => $this->parser->chomp( $data['result'] ),
- 'options' => $this->parser->chomp( $data['options'] ),
- 'config' => $this->parser->chomp( $data['config'] ) );
- } else {
- $this->test['test'] = $data['test'];
- }
-
- return true;
- }
-
- if ( isset ( $data[$section] ) ) {
- wfDie( "duplicate section '$section' at line {$this->lineNum} of $this->file\n" );
- }
-
- $data[$section] = '';
-
- continue;
- }
-
- if ( $section ) {
- $data[$section] .= $line;
- }
- }
-
- return false;
- }
-}
+++ /dev/null
-<?php
-# Copyright (C) 2004 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
-
-/**
- * @file
- * @ingroup Maintenance
- */
-
-$options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled' );
-$optionsWithArgs = array( 'regex', 'seed', 'setversion' );
-
-require_once( dirname( __FILE__ ) . '/commandLine.inc' );
-require_once( dirname( __FILE__ ) . '/parserTests.inc' );
-
-if ( isset( $options['help'] ) ) {
- echo <<<ENDS
-MediaWiki $wgVersion parser test suite
-Usage: php parserTests.php [options...]
-
-Options:
- --quick Suppress diff output of failed tests
- --quiet Suppress notification of passed tests (shows only failed tests)
- --show-output Show expected and actual output
- --color[=yes|no] Override terminal detection and force color output on or off
- use wgCommandLineDarkBg = true; if your term is dark
- --regex Only run tests whose descriptions which match given regex
- --file=<testfile> Run test cases from a custom file instead of parserTests.txt
- --record Record tests in database
- --compare Compare with recorded results, without updating the database.
- --setversion When using --record, set the version string to use (useful
- with git-svn so that you can get the exact revision)
- --keep-uploads Re-use the same upload directory for each test, don't delete it
- --fuzz Do a fuzz test instead of a normal test
- --seed <n> Start the fuzz test from the specified seed
- --help Show this help message
- --run-disabled run disabled tests
- --upload Upload test results to remote wiki (per \$wgParserTestRemote)
-
-ENDS;
- exit( 0 );
-}
-
-# Cases of weird db corruption were encountered when running tests on earlyish
-# versions of SQLite
-if ( $wgDBtype == 'sqlite' ) {
- $db = wfGetDB( DB_MASTER );
- $version = $db->getServerVersion();
- if ( version_compare( $version, '3.6' ) < 0 ) {
- die( "Parser tests require SQLite version 3.6 or later, you have $version\n" );
- }
-}
-
-# There is a convention that the parser should never
-# refer to $wgTitle directly, but instead use the title
-# passed to it.
-$wgTitle = Title::newFromText( 'Parser test script do not use' );
-$tester = new ParserTest($options);
-
-if ( isset( $options['file'] ) ) {
- $files = array( $options['file'] );
-} else {
- // Default parser tests and any set from extensions or local config
- $files = $wgParserTestFiles;
-}
-
-# Print out software version to assist with locating regressions
-$version = SpecialVersion::getVersion();
-echo( "This is MediaWiki version {$version}.\n\n" );
-
-if ( isset( $options['fuzz'] ) ) {
- $tester->fuzzTest( $files );
-} else {
- $ok = $tester->runTestsFromFiles( $files );
- exit ( $ok ? 0 : 1 );
-}
+++ /dev/null
-# MediaWiki Parser test cases
-# Some taken from http://meta.wikimedia.org/wiki/Parser_testing
-# All (C) their respective authors and released under the GPL
-#
-# The syntax should be fairly self-explanatory.
-#
-# Currently supported test options:
-# One of the following three:
-#
-# (default) generate HTML output
-# pst apply pre-save transform
-# msg apply message transform
-#
-# Plus any combination of these:
-#
-# cat add category links
-# ill add inter-language links
-# subpage enable subpages (disabled by default)
-# noxml don't check for XML well formdness
-# title=[[XXX]] run test using article title XXX
-# language=XXX set content language to XXX for this test
-# variant=XXX set the variant of language for this test (eg zh-tw)
-# disabled do not run test
-# showtitle make the first line the title
-# comment run through Linker::formatComment() instead of main parser
-# local format section links in edit comment text as local links
-#
-# For testing purposes, temporary articles can created:
-# !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
-# where '/' denotes a newline.
-
-# This is the standard article assumed to exist.
-!! article
-Main Page
-!! text
-blah blah
-!! endarticle
-
-!!article
-Template:Foo
-!!text
-FOO
-!!endarticle
-
-!! article
-Template:Blank
-!! text
-!! endarticle
-
-!! article
-Template:!
-!! text
-|
-!! endarticle
-
-!!article
-MediaWiki:bad image list
-!!text
-* [[File:Bad.jpg]] except [[Nasty page]]
-!!endarticle
-
-###
-### 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
-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
-
-###
-### <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
-
-
-###
-### Comments
-###
-!! test
-Comment test 1
-!! input
-<!-- comment 1 --> asdf
-<!-- comment 2 -->
-!! result
-<pre>asdf
-</pre>
-
-!! end
-
-!! test
-Comment test 2
-!! input
-asdf
-<!-- comment 1 -->
-jkl
-!! result
-<p>asdf
-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
-
-###
-### 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
-<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
-
-# Expected output in the following test is not really expected (there should be
-# <pre> in the output) -- it's only testing for well-formedness.
-!! test
-Bug 6200: Preformatted in <blockquote>
-!! input
-<blockquote>
- Blah
-</blockquote>
-!! result
-<blockquote>
- Blah
-</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
-<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
-
-###
-### 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 href="http://example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow">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 href="news:alt.wikipedia.rox" class="external free" rel="nofollow">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 href="news:alt.wikipedia.rox" class="external free" rel="nofollow">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 href="http://www.wikipedia2.org/" class="external text" rel="nofollow">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
-
-
-###
-### External links
-###
-!! test
-External links: non-bracketed
-!! input
-Non-bracketed: http://example.com
-!! result
-<p>Non-bracketed: <a href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external autonumber" rel="nofollow">[1]</a>
-Numbered: <a href="http://example.net" class="external autonumber" rel="nofollow">[2]</a>
-Numbered: <a href="http://example.com" class="external autonumber" rel="nofollow">[3]</a>
-</p>
-!!end
-
-!! test
-External links: specified text
-!! input
-Specified text: [http://example.com link]
-!! result
-<p>Specified text: <a href="http://example.com" class="external text" rel="nofollow">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 href="http://example.com" class="external text" rel="nofollow">link</a>s
-</p>
-!! end
-
-!! test
-External links: dollar sign in URL
-!! input
-http://example.com/1$2345
-!! result
-<p><a href="http://example.com/1$2345" class="external free" rel="nofollow">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 href="http://example.com/1$2345" class="external autonumber" rel="nofollow">[1]</a>
-</p>
-!!end
-
-!! test
-External links: open square bracket forbidden in URL (bug 4377)
-!! input
-http://example.com/1[2345
-!! result
-<p><a href="http://example.com/1" class="external free" rel="nofollow">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 href="http://example.com/1" class="external text" rel="nofollow">[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 href="http://example.com/" class="external text" rel="nofollow">''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 href="http://example.com/" class="external free" rel="nofollow">http://example.com/</a> first
-second]
-</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
-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 href="ftp://example.com/test.jpg" class="external free" rel="nofollow">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 href="http://example.com/thing" class="external free" rel="nofollow">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 href="http://example.com/1,2,3" class="external free" rel="nofollow">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 href="http://example.com/thing?url=http://example.com" class="external text" rel="nofollow">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 href="ftp://example.com?url=http://example.com" class="external text" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external text" rel="nofollow"><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 href="http://x&y" class="external free" rel="nofollow">http://x&y</a>
-</p>
-!! end
-
-!! test
-External links: encoded ampersand
-!! input
-Old & use: http://x&y
-!! result
-<p>Old & use: <a href="http://x&y" class="external free" rel="nofollow">http://x&y</a>
-</p>
-!! end
-
-!! test
-External links: encoded equals (bug 6102)
-!! input
-http://example.com/?foo=bar
-!! result
-<p><a href="http://example.com/?foo=bar" class="external free" rel="nofollow">http://example.com/?foo=bar</a>
-</p>
-!! end
-
-!! test
-External links: [raw ampersand]
-!! input
-Old & use: [http://x&y]
-!! result
-<p>Old & use: <a href="http://x&y" class="external autonumber" rel="nofollow">[1]</a>
-</p>
-!! end
-
-!! test
-External links: [encoded ampersand]
-!! input
-Old & use: [http://x&y]
-!! result
-<p>Old & use: <a href="http://x&y" class="external autonumber" rel="nofollow">[1]</a>
-</p>
-!! end
-
-!! test
-External links: [encoded equals] (bug 6102)
-!! input
-[http://example.com/?foo=bar]
-!! result
-<p><a href="http://example.com/?foo=bar" class="external autonumber" rel="nofollow">[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 href="http://example.com/" class="external autonumber" rel="nofollow">[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 href="http://example.com/" class="external free" rel="nofollow">http://example.com/</a>
-</p>
-!! end
-
-!! test
-External links: www.jpeg.org (bug 554)
-!! input
-http://www.jpeg.org
-!!result
-<p><a href="http://www.jpeg.org" class="external free" rel="nofollow">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 href="http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp" class="external autonumber" rel="nofollow">[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 href="http://www.example.com/foo" class="external text" rel="nofollow">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 href="http://www.example.com/foo?=http://www.example.com/bar" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow"><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 href="http://www.example.com/" class="external text" rel="nofollow"><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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow">"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 href="http://www.example.com" class="external text" rel="nofollow">test</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 href="http://example.com" class="external text" rel="nofollow"></a><a href="/index.php?title=Wikilink&action=edit&redlink=1" class="new" title="Wikilink (page does not exist)">wikilink</a><a href="http://example.com" class="external text" rel="nofollow"> 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
-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 href="http://example.com" class="external text" rel="nofollow"><i>text</i></a>
-<a href="http://example.com" class="external text" rel="nofollow"><b>text</b></a>
-<i>Something </i><a href="http://example.com" class="external text" rel="nofollow"><i>in italic</i></a>
-<i>Something </i><a href="http://example.com" class="external text" rel="nofollow"><i>mixed</i><b>, even bold</b></a>
-<i><b>Now </b></i><a href="http://example.com" class="external text" rel="nofollow"><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 href="http://www.example.com/?title=AT%26T" class="external free" rel="nofollow">http://www.example.com/?title=AT%26T</a>
-</p>
-!! end
-
-!! test
-Bug 4781, 5267: %26 in URL
-!! input
-http://www.example.com/?title=100%25_Bran
-!! result
-<p><a href="http://www.example.com/?title=100%25_Bran" class="external free" rel="nofollow">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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external free" rel="nofollow">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 href="http://www.example.com/?title=AT%26T" class="external autonumber" rel="nofollow">[1]</a>
-</p>
-!! end
-
-!! test
-Bug 4781, 5267: %26 in autonumber URL
-!! input
-[http://www.example.com/?title=100%25_Bran]
-!! result
-<p><a href="http://www.example.com/?title=100%25_Bran" class="external autonumber" rel="nofollow">[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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external autonumber" rel="nofollow">[1]</a>
-</p>
-!! end
-
-
-!! test
-Bug 4781: %26 in bracketed URL
-!! input
-[http://www.example.com/?title=AT%26T link]
-!! result
-<p><a href="http://www.example.com/?title=AT%26T" class="external text" rel="nofollow">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 href="http://www.example.com/?title=100%25_Bran" class="external text" rel="nofollow">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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external text" rel="nofollow">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 href="http://example.com/" class="external text" rel="nofollow">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 href="http://example.com/" class="external text" rel="nofollow"><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 href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm" class="external text" rel="nofollow"><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
-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
-
-###
-### 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
-!! 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.
-!! 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>
-!! 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 minimun required by the spec, see:
-# http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables
-!! test
-A table with no data.
-!! input
-{||}
-!! result
-!! end
-
-# A table with nothing but a caption is invalid XHTML, we might want to render
-# this as <p>caption</p>
-!! test
-A table with nothing but a caption
-!! input
-{|
-|+ caption
-|}
-!! result
-<table>
-<caption> caption
-</caption><tr><td></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
-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
-Table rowspan
-!! input
-{| align=right 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 align="right" 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 href="ftp://%7Cx" class="external free" rel="nofollow">ftp://%7Cx</a></td>
-<td>]" onmouseover="alert(document.cookie)">test
-</td>
-</tr>
-</table>
-
-!! 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
-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
-
-!! 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
-
-!! 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 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
-Plain link to URL
-!! input
-[[http://www.example.com]]
-!! result
-<p>[<a href="http://www.example.com" class="external autonumber" rel="nofollow">[1]</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 href="http://www.example.com%7Can" class="external text" rel="nofollow">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
-
-
-###
-### 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
-
-!! 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
-
-
-##
-## XHTML tidiness
-###
-
-!! test
-<br> to <br />
-!! input
-1<br>2<br />3
-!! result
-<p>1<br />2<br />3
-</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 clear=left>
-<br clear=right>
-<br clear=all>
-!! result
-<p><br clear="left" />
-<br clear="right" />
-<br clear="all" />
-</p>
-!!end
-
-!! test
-Horizontal ruler (should it add that extra space?)
-!! input
-<hr>
-<hr >
-foo <hr
-> bar
-!! result
-<hr />
-<hr />
-foo <hr /> bar
-
-!! 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
-!! 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
-</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
-
-###
-### Magic Words
-###
-
-!! 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: {{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: {{CURRENTWEEK}} (@bug 4594)
-!! input
-{{CURRENTWEEK}}
-!! result
-<p>1
-</p>
-!! end
-
-!! test
-Magic Word: {{CURRENTYEAR}}
-!! input
-{{CURRENTYEAR}}
-!! result
-<p>1970
-</p>
-!! 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: {{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: {{NUMBEROFFILES}}
-!! input
-{{NUMBEROFFILES}}
-!! result
-<p>2
-</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: {{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: {{REVISIONID}}
-!! input
-{{REVISIONID}}
-!! result
-<p>1337
-</p>
-!! end
-
-!! test
-Magic Word: {{SCRIPTPATH}}
-!! input
-{{SCRIPTPATH}}
-!! result
-<p>/
-</p>
-!! end
-
-!! test
-Magic Word: {{SERVER}}
-!! input
-{{SERVER}}
-!! result
-<p><a href="http://localhost" class="external free" rel="nofollow">http://localhost</a>
-</p>
-!! end
-
-!! test
-Magic Word: {{SERVERNAME}}
-!! input
-{{SERVERNAME}}
-!! result
-<p>Britney-Spears
-</p>
-!! end
-
-!! test
-Magic Word: {{SITENAME}}
-!! input
-{{SITENAME}}
-!! result
-<p>MediaWiki
-</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 href="http://tools.ietf.org/html/rfc822" class="external mw-magiclink-rfc">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 href="http://www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" class="external mw-magiclink-pmid">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
-
-!! 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
-
-
-!!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}}]]
-!! result
-<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>
-</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
-
-
-!! 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
-<onlyinclude> on a page
-!! input
-<onlyinclude>Foo</onlyinclude>bar
-!! result
-<p>Foobar
-</p>
-!! 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="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Includeonly_section">Includeonly section</span></h2>
-<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Section_T-1">Section T-1</span></h2>
-
-!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2>
-
-!! 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
-
-###
-### 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
-
-!! 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: comment containing math
-!! options
-pst
-!! input
-<!-- <math>data</math> -->
-!!result
-<!-- <math>data</math> -->
-!!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
-
-
-###
-### 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:foobarnonexistent}}
-!! result
-No such special page
-!! end
-
-###
-### Images
-###
-!! test
-Simple image
-!! 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
-Right-aligned image
-!! 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
-Simple image (using File: namespace, now canonical)
-!! 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
-Image with caption
-!! input
-[[Image: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 link parameter, wiki target
-!! input
-[[Image:foobar.jpg|link=Target page]]
-!! result
-<p><a href="/wiki/Target_page" title="Target page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
-</p>
-!! end
-
-!! test
-Image with link parameter, URL target
-!! input
-[[Image:foobar.jpg|link=http://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 empty link parameter
-!! input
-[[Image:foobar.jpg|link=]]
-!! result
-<p><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" />
-</p>
-!! end
-
-!! test
-Image with link parameter (wiki target) and unnamed parameter
-!! input
-[[Image:foobar.jpg|link=Target page|Title]]
-!! result
-<p><a href="/wiki/Target_page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
-</p>
-!! end
-
-!! test
-Image with link parameter (URL target) and unnamed parameter
-!! input
-[[Image:foobar.jpg|link=http://example.com/|Title]]
-!! result
-<p><a href="http://example.com/" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
-</p>
-!! end
-
-!! test
-Thumbnail image with link parameter
-!! 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/3/3a/Foobar.jpg" width="180" height="20" 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/3/3a/Foobar.jpg" width="180" height="20" 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><a href="http://example.com" class="external free" rel="nofollow">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/3/3a/Foobar.jpg" width="180" height="20" 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><a href="http://example.com" class="external free" rel="nofollow">http://example.com</a></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/3/3a/Foobar.jpg" width="180" height="20" 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><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/3/3a/Foobar.jpg" width="180" height="20" 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>This is <a href="http://tools.ietf.org/html/rfc12354" class="external mw-magiclink-rfc">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/3/3a/Foobar.jpg" width="180" height="20" 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>Please <a href="mailto:nobody@example.com" class="external free" rel="nofollow">mailto:nobody@example.com</a></div></div></div>
-
-!! end
-
-!! test
-BUG 1887: A <math> with a thumbnail- we don't render math in the parsertests by default,
-so math is not stripped and turns up as escaped <math> tags.
-!! input
-[[Image:foobar.jpg|thumb|<math>2+2</math>]]
-!! 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/3/3a/Foobar.jpg" width="180" height="20" 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><math>2+2</math></div></div></div>
-
-!! end
-
-!! test
-BUG 1887, part 2: A <math> with a thumbnail- math enabled
-!! options
-math
-!! input
-[[Image:foobar.jpg|thumb|<math>2+2</math>]]
-!! 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/3/3a/Foobar.jpg" width="180" height="20" 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><span class="texhtml">2 + 2</span></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/3/3a/Foobar.jpg" width="180" height="20" 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>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
-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/3/3a/Foobar.jpg" width="200" height="23" 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>This caption has <a href="irc://example.net" class="external text" rel="nofollow">irc</a> and <a href="https://example.com" class="external text" rel="nofollow">Secure</a> ext links in it.</div></div></div>
-
-!! 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
-
-
-###
-### 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
-
-!! 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
-
-###
-### Inter-language links
-###
-!! test
-Inter-language links
-!! options
-ill
-!! input
-[[es:Alimento]]
-[[fr:Nourriture]]
-[[zh:食品]]
-!! result
-es:Alimento fr:Nourriture zh:食品
-!! end
-
-###
-### Sections
-###
-!! test
-Basic section headings
-!! input
-== Headline 1 ==
-Some text
-
-==Headline 2==
-More
-===Smaller headline===
-Blah blah
-!! result
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2>
-<p>Some text
-</p>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2">Headline 2</span></h2>
-<p>More
-</p>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a>]</span> <span class="mw-headline" id="Smaller_headline">Smaller headline</span></h3>
-<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
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a>]</span> <span class="mw-headline" id="Subheadline_1"> Subheadline 1 </span></h3>
-<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level"> Skipping a level </span></h5>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level_2"> Skipping a level </span></h6>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2"> Headline 2 </span></h2>
-<p>Some text
-</p>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a>]</span> <span class="mw-headline" id="Another_headline">Another headline</span></h3>
-
-!! 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
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline" id="Level_1_Heading"> Level 1 Heading</span></h1>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline" id="Level_2_Heading"> Level 2 Heading</span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a>]</span> <span class="mw-headline" id="Level_3_Heading"> Level 3 Heading</span></h3>
-<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline" id="Level_4_Heading"> Level 4 Heading</span></h4>
-<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline" id="Level_5_Heading"> Level 5 Heading</span></h5>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline" id="Level_6_Heading"> Level 6 Heading</span></h6>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span></h6>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span></h6>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span></h6>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span></h6>
-
-!! 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
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
-<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3>
-
-!! 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
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
-<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3>
-
-!! 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
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1">Section 1.1</span></h3>
-<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span></h4>
-<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span></h4>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2>
-
-!! end
-
-
-!! test
-Resolving duplicate section names
-!! input
-== Foo bar ==
-== Foo bar ==
-!! result
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar_2"> Foo bar </span></h2>
-
-!! end
-
-!! test
-Resolving duplicate section names with differing case (bug 10721)
-!! input
-== Foo bar ==
-== Foo Bar ==
-!! result
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> Foo Bar </span></h2>
-
-!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a>]</span> <span class="mw-headline" id="Section_0">Section 0</span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h3>
-<h2><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a>]</span> <span class="mw-headline" id="Section_4">Section 4</span></h2>
-
-!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a>]</span> <span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span></h2>
-
-!! end
-
-!! test
-TOC regression (bug 12077)
-!! input
-__TOC__
-== title 1 ==
-=== title 1.1 ===
-== title 2 ==
-!! result
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
-
-!! end
-
-!! test
-BUG 1219 URL next to image (good)
-!! input
-http://example.com [[Image:foobar.jpg]]
-!! result
-<p><a href="http://example.com" class="external free" rel="nofollow">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 behaviour 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D">=</span></h1>
-<p>The line above must have a trailing space!
-</p>
-<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D_2">=</span></h1>
-<p>But just in case it doesn't...
-</p>
-!! end
-
-!! test
-BUG 1219 URL next to image (broken)
-!! input
-http://example.com[[Image:foobar.jpg]]
-!! result
-<p><a href="http://example.com" class="external free" rel="nofollow">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 href="http://en.wikinews.org/wiki/Wikinews:Workplace" class="external free" rel="nofollow">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
-
-
-!! 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 align="center" align="right">HTML rocks</div>
-!! result
-<div align="right">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 ALIGN="center">HTML ROCKS</DIV>
-!! result
-<div align="center">HTML ROCKS</div>
-
-!!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 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
-
-
-###
-### 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
-Math section safety when disabled
-!! input
-<math><script>alert(document.cookies);</script></math>
-!! result
-<p><math><script>alert(document.cookies);</script></math>
-</p>
-!! 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
-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 maintenance/parserTestsParserHook.php for the <tag> extension)
-###
-!! test
-Parser hook: empty input
-!! input
-<tag></tag>
-!! result
-<pre>
-string(0) ""
-array(0) {
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: empty input using terminated empty elements
-!! input
-<tag/>
-!! result
-<pre>
-NULL
-array(0) {
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: empty input using terminated empty elements (space before)
-!! input
-<tag />
-!! result
-<pre>
-NULL
-array(0) {
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: basic input
-!! input
-<tag>input</tag>
-!! result
-<pre>
-string(5) "input"
-array(0) {
-}
-</pre>
-
-!! end
-
-
-!! test
-Parser hook: case insensitive
-!! input
-<TAG>input</TAG>
-!! result
-<pre>
-string(5) "input"
-array(0) {
-}
-</pre>
-
-!! end
-
-
-!! test
-Parser hook: case insensitive, redux
-!! input
-<TaG>input</TAg>
-!! result
-<pre>
-string(5) "input"
-array(0) {
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: nested tags
-!! options
-noxml
-!! input
-<tag><tag></tag></tag>
-!! result
-<pre>
-string(5) "<tag>"
-array(0) {
-}
-</pre></tag>
-
-!! end
-
-!! test
-Parser hook: basic arguments
-!! input
-<tag width=200 height = "100" depth = '50' square></tag>
-!! result
-<pre>
-string(0) ""
-array(4) {
- ["width"]=>
- string(3) "200"
- ["height"]=>
- string(3) "100"
- ["depth"]=>
- string(2) "50"
- ["square"]=>
- string(6) "square"
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: argument containing a forward slash (bug 5344)
-!! input
-<tag filename='/tmp/bla'></tag>
-!! result
-<pre>
-string(0) ""
-array(1) {
- ["filename"]=>
- string(8) "/tmp/bla"
-}
-</pre>
-
-!! end
-
-!! test
-Parser hook: empty input using terminated empty elements (bug 2374)
-!! input
-<tag foo=bar/>text
-!! result
-<pre>
-NULL
-array(1) {
- ["foo"]=>
- string(3) "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(4) {
- ["width"]=>
- string(3) "200"
- ["height"]=>
- string(3) "100"
- ["depth"]=>
- string(2) "50"
- ["square"]=>
- string(6) "square"
-}
-</pre>
-<p>other stuff
-</tag>
-</p>
-!! end
-
-###
-### (see maintenance/parserTestsStaticParserHook.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
-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 href="http://first/" class="external autonumber" rel="nofollow">[1]</a> <a href="http://second" class="external autonumber" rel="nofollow">[2]</a> <a href="ftp://ftp" class="external autonumber" rel="nofollow">[3]</a>
-</p><p><a href="ftp://inlineftp" class="external free" rel="nofollow">ftp://inlineftp</a>
-</p><p><a href="mailto:enclosed@mail.tld" class="external text" rel="nofollow">With target</a>
-</p><p><a href="mailto:enclosed@mail.tld" class="external autonumber" rel="nofollow">[4]</a>
-</p><p><a href="mailto:inline@mail.tld" class="external free" rel="nofollow">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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a>]</span> <span class="mw-headline" id="onmouseover.3D"> onmouseover= </span></h2>
-http://<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div>
-<ul>
-<li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
-</ul>
-</td></tr></table>
-
-!! end
-
-!! test
-Fuzz testing: Parser14-table
-!! input
-==a==
-{| STYLE=__TOC__
-!! result
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2>
-<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 href="irc://{{ftp://a" class="external free" rel="nofollow">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 href="http://===r:::https://b" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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:1943px;">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
-<p><br />
-</p>
-<table border="0" 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
-<p><br />
-</p>
-<table border="0" id="mw-prefixindex-list-table"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table>
-<p><br />
-</p>
-<table border="0" 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 behaviour of bug 19910
-!! test
-Sectiion with all-equals
-!! options
-section=2
-!! input
-===
-The line above must have a trailing space
-=== <!--
---> <!-- -->
-But just in case it doesn't...
-!! result
-=== <!--
---> <!-- -->
-But just in case it doesn't...
-!! end
-
-!! test
-Section replacement test (section 0)
-!! options
-replace=0,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-xxx
-
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 1)
-!! options
-replace=1,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-xxx
-
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 2)
-!! options
-replace=2,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-xxx
-
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 3)
-!! options
-replace=3,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-xxx
-
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 4)
-!! options
-replace=4,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-xxx
-
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 5)
-!! options
-replace=5,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-xxx
-
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 6)
-!! options
-replace=6,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-xxx
-
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 7)
-!! options
-replace=7,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-xxx
-
-===bc===
-==c==
-===ca===
-!! end
-
-!! test
-Section replacement test (section 8)
-!! options
-replace=8,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-xxx
-
-==c==
-===ca===
-!!end
-
-!! test
-Section replacement test (section 9)
-!! options
-replace=9,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-xxx
-!! end
-
-!! test
-Section replacement test (section 10)
-!! options
-replace=10,"xxx"
-!! input
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-===ca===
-!! result
-start
-==a==
-===aa===
-====aaa====
-==b==
-===ba===
-===bb===
-====bba====
-===bc===
-==c==
-xxx
-!! end
-
-!! test
-Section replacement test with initial whitespace (bug 13728)
-!! options
-replace=2,"xxx"
-!! input
- Preformatted initial line
-==a==
-===a===
-!! result
- Preformatted initial line
-==a==
-xxx
-!! end
-
-
-!! test
-Section extraction, heading followed by pre with 20 spaces (bug 6398)
-!! options
-section=1
-!! input
-==a==
- a
-!! result
-==a==
- a
-!! end
-
-!! test
-Section extraction, heading followed by pre with 19 spaces (bug 6398 sanity check)
-!! options
-section=1
-!! input
-==a==
- a
-!! result
-==a==
- a
-!! end
-
-
-!! test
-Section extraction, <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 href="irc://%0Aa" class="external free" rel="nofollow">irc://%0Aa</a>
-</li></ul>
-</li></ul>
-
-!!end
-
-!! test
-5 quotes, code coverage +1 line
-!! input
-'''''
-!! result
-!! 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
-!! input
-* {{PAGENAME}}
-* {{BASEPAGENAME}}
-* {{SUBPAGENAME}}
-* {{SUBPAGENAMEE}}
-* {{BASEPAGENAME}}
-* {{BASEPAGENAMEE}}
-* {{TALKPAGENAME}}
-* {{TALKPAGENAMEE}}
-* {{SUBJECTPAGENAME}}
-* {{SUBJECTPAGENAMEE}}
-* {{NAMESPACEE}}
-* {{NAMESPACE}}
-* {{TALKSPACE}}
-* {{TALKSPACEE}}
-* {{SUBJECTSPACE}}
-* {{SUBJECTSPACEE}}
-* {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}}
-!! result
-<ul><li> Parser test
-</li><li> Parser test
-</li><li> Parser test
-</li><li> Parser_test
-</li><li> Parser test
-</li><li> Parser_test
-</li><li> Talk:Parser test
-</li><li> Talk:Parser_test
-</li><li> Parser test
-</li><li> Parser_test
-</li><li>
-</li><li>
-</li><li> Talk
-</li><li> Talk
-</li><li>
-</li><li>
-</li><li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a>
-</li></ul>
-
-!! 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
-<table class="gallery" cellspacing="0" cellpadding="0">
- <tr>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Image1.png</div>
- <div class="gallerytext">
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Image2.gif</div>
- <div class="gallerytext">
-<p>||||
-</p>
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Image3</div>
- <div class="gallerytext">
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Image4</div>
- <div class="gallerytext">
-<p>300px| centre
-</p>
- </div>
- </div></td>
- </tr>
- <tr>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Image5.svg</div>
- <div class="gallerytext">
-<p><a href="http://///////" class="external free" rel="nofollow">http://///////</a>
-</p>
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">* image6</div>
- <div class="gallerytext">
- </div>
- </div></td>
- </tr>
-</table>
-
-!! end
-
-!! test
-Gallery (with options)
-!! input
-<gallery widths='60px' 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
-</gallery>
-!! result
-<table class="gallery" cellspacing="0" cellpadding="0">
- <caption>Foo <a href="/wiki/Main_Page" title="Main Page">Main Page</a></caption>
- <tr>
- <td><div class="gallerybox" style="width: 95px;">
- <div style="height: 52px;">Nonexistant.jpg</div>
- <div class="gallerytext">
-<p>caption
-</p>
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 95px;">
- <div style="height: 52px;">Nonexistant.jpg</div>
- <div class="gallerytext">
- </div>
- </div></td>
- </tr>
- <tr>
- <td><div class="gallerybox" style="width: 95px;">
- <div class="thumb" style="padding: 19px 0; width: 90px;"><div style="margin-left: auto; margin-right: auto; width: 60px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="60" height="7" /></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></td>
- <td><div class="gallerybox" style="width: 95px;">
- <div class="thumb" style="padding: 19px 0; width: 90px;"><div style="margin-left: auto; margin-right: auto; width: 60px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="60" height="7" /></a></div></div>
- <div class="gallerytext">
- </div>
- </div></td>
- </tr>
-</table>
-
-!! 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
-<table class="gallery" cellspacing="0" cellpadding="0">
- <tr>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">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></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div style="height: 152px;">Nonexistant.jpg</div>
- <div class="gallerytext">
-<p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br />
-</p>
- </div>
- </div></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div class="thumb" style="padding: 66px 0; width: 150px;"><div style="margin-left: auto; margin-right: auto; width: 120px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/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></td>
- <td><div class="gallerybox" style="width: 155px;">
- <div class="thumb" style="padding: 66px 0; width: 150px;"><div style="margin-left: auto; margin-right: auto; width: 120px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/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></td>
- </tr>
-</table>
-
-!! end
-
-!! test
-HTML Hex character encoding (spells the word "JavaScript")
-!! input
-JavaScript
-!! result
-<p>JavaScript
-</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 href="http://www.example.com" class="external text" rel="nofollow">example.com</a>
-</p>
-!! end
-
-!! test
-Double RFC
-!! input
-RFC RFC 1234
-!! result
-<p>RFC <a href="http://tools.ietf.org/html/rfc1234" class="external mw-magiclink-rfc">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 href="http://tools.ietf.org/html/rfc983" class="external mw-magiclink-rfc">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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="180" height="20" 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>An <a href="http://test/?param1=%7Cleft%7C&param2=%7Cx" class="external text" rel="nofollow">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
-rawhtml
-!! 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
-
-!! 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="editsection">[<a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a>]</span> <span class="mw-headline" id="header">header</span></h2>
-
-!! end
-
-
-!! test
-Out-of-order TOC heading levels
-!! input
-==2==
-======6======
-===3===
-=1=
-=====5=====
-==2==
-!! result
-<table id="toc" class="toc"><tr><td><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>
-</td></tr></table>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2">2</span></h2>
-<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a>]</span> <span class="mw-headline" id="6">6</span></h6>
-<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a>]</span> <span class="mw-headline" id="3">3</span></h3>
-<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a>]</span> <span class="mw-headline" id="1">1</span></h1>
-<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a>]</span> <span class="mw-headline" id="5">5</span></h5>
-<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2_2">2</span></h2>
-
-!! 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
-
-# Expected output in the following test is not necessarily expected (there
-# should probably be <p> tags inside the <blockquote> in the output) -- it's
-# only testing for well-formedness.
-!! test
-Bug 6200: blockquotes and paragraph formatting
-!! input
-<blockquote>
-foo
-</blockquote>
-
-bar
-
- baz
-!! result
-<blockquote>
-foo
-</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
-
-
-###
-### 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
-
-
-!! 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
-
-
-!! 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="/index.php?title=Main_Page&variant=sr-ec" 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Уреди део: Naslov">уреди</a>]</span> <span class="mw-headline" id="-.7BNaslov.7D-"> Naslov </span></h2>
-
-!! 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
-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
-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
-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
-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
-
-!!article
-Template:Bullet
-!!text
-* Bar
-!!endarticle
-
-!! test
-Bug 529: Uncovered bullet
-!! input
-* Foo {{bullet}}
-!! result
-<ul><li> Foo
-</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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2>
-
-!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2>
-
-!! 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)
-!! options
-disabled
-!! 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)
-!! options
-disabled
-!! 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)
-!! options
-disabled
-!! 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)
-!! options
-disabled
-!! 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/3/3a/Foobar.jpg" width="180" height="20" 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>hello</div></div></div>
-
-!! end
-
-!! test
-Bug 15196: localised external link numbers
-!! options
-language=fa
-!! input
-[http://en.wikipedia.org/]
-!! result
-<p><a href="http://en.wikipedia.org/" class="external autonumber" rel="nofollow">[۱]</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
-Formatted date
-!! config
-wgUseDynamicDates=1
-!! input
-[[2009-03-24]]
-!! result
-<p><span class="mw-formatted-date" title="2009-03-24"><a href="/index.php?title=2009&action=edit&redlink=1" class="new" title="2009 (page does not exist)">2009</a>-<a href="/index.php?title=March_24&action=edit&redlink=1" class="new" title="March 24 (page does not exist)">03-24</a></span>
-</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
-Linked date with autoformatting disabled
-!! config
-wgUseDynamicDates=false
-!! input
-[[2009-03-24]]
-!! result
-<p><a href="/index.php?title=2009-03-24&action=edit&redlink=1" class="new" title="2009-03-24 (page does not exist)">2009-03-24</a>
-</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
-Spacing of numbers in formatted dates (linked)
-!! config
-wgUseDynamicDates=true
-!! input
-[[January 15]]
-!! result
-<p><span class="mw-formatted-date" title="01-15"><a href="/index.php?title=January_15&action=edit&redlink=1" class="new" title="January 15 (page does not exist)">January 15</a></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
-<span class="autocomment"><a href="/wiki/Main_Page#External_links" title="Main Page">→</a>External links: </span> removed bogus entries
-!!end
-
-!! test
-Edit comment with section link (local, eg in diff view)
-!! options
-comment local title=[[Main Page]]
-!! input
-/* External links */ removed bogus entries
-!! result
-<span class="autocomment"><a href="#External_links">→</a>External links: </span> removed bogus entries
-!!end
-
-!! test
-Edit comment with subpage link (bug 14080)
-!! options
-comment
-subpage
-title=[[Subpage test]]
-!! input
-Poked at a [[/subpage]] here...
-!! result
-Poked at a <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
-Space normalisation on autocomment (bug 22784)
-!! options
-comment
-title=[[Main Page]]
-!!input
-/* __hello__world__ */
-!! result
-<span class="autocomment"><a href="/wiki/Main_Page#hello_world" title="Main Page">→</a>__hello__world__</span>
-!! end
-
-!! test
-Bad images - basic functionality
-!! input
-[[File:Bad.jpg]]
-!! result
-!! end
-
-!! test
-Bad images - bug 16039: text after bad image disappears
-!! 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
-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
-
-
-TODO:
-more images
-more tables
-math
-character entities
-and much more
-Try for 100% code coverage
+++ /dev/null
-<?php
-/**
- * A basic extension that's used by the parser tests to test whether input and
- * arguments are passed to extensions properly.
- *
- * Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
- *
- * 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 Maintenance
- * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- */
-
-class ParserTestParserHook {
-
- static function setup( &$parser ) {
- $parser->setHook( 'tag', array( __CLASS__, 'hook' ) );
-
- return true;
- }
-
- static function hook( $in, $argv ) {
- ob_start();
- var_dump(
- $in,
- $argv
- );
- $ret = ob_get_clean();
-
- return "<pre>\n$ret</pre>";
- }
-}
+++ /dev/null
-<?php
-/**
- * A basic extension that's used by the parser tests to test whether the parser
- * calls extensions when they're called inside comments, it shouldn't do that
- *
- * Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
- *
- * 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 Maintenance
- * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- */
-
-class ParserTestStaticParserHook {
- static function setup( &$parser ) {
- $parser->setHook( 'statictag', array( __CLASS__, 'hook' ) );
-
- return true;
- }
-
- static function hook( $in, $argv, $parser ) {
- if ( ! count( $argv ) ) {
- $parser->static_tag_buf = $in;
- return '';
- } else if ( count( $argv ) === 1 && isset( $argv['action'] )
- && $argv['action'] === 'flush' && $in === null )
- {
- // Clear the buffer, we probably don't need to
- if ( isset( $parser->static_tag_buf ) ) {
- $tmp = $parser->static_tag_buf;
- } else {
- $tmp = '';
- }
- $parser->static_tag_buf = null;
- return $tmp;
- } else
- // wtf?
- return
- "\nCall this extension as <statictag>string</statictag> or as" .
- " <statictag action=flush/>, not in any other way.\n" .
- "text: " . var_export( $in, true ) . "\n" .
- "argv: " . var_export( $argv, true ) . "\n";
- }
-}
--- /dev/null
+<?php
+# Copyright (C) 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 Maintenance
+ */
+
+/**
+ * @ingroup Maintenance
+ */
+class ParserTest {
+ /**
+ * boolean $color whereas output should be colorized
+ */
+ private $color;
+
+ /**
+ * boolean $showOutput Show test output
+ */
+ private $showOutput;
+
+ /**
+ * boolean $useTemporaryTables Use temporary tables for the temporary database
+ */
+ private $useTemporaryTables = true;
+
+ /**
+ * boolean $databaseSetupDone True if the database has been set up
+ */
+ private $databaseSetupDone = false;
+
+ /**
+ * string $oldTablePrefix Original table prefix
+ */
+ private $oldTablePrefix;
+
+ private $maxFuzzTestLength = 300;
+ private $fuzzSeed = 0;
+ private $memoryLimit = 50;
+
+ /**
+ * Sets terminal colorization and diff/quick modes depending on OS and
+ * command-line options (--color and --quick).
+ */
+ public function ParserTest( $options = array() ) {
+ # Only colorize output if stdout is a terminal.
+ $this->color = !wfIsWindows() && 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['regex'] ) ) {
+ if ( isset( $options['record'] ) ) {
+ echo "Warning: --record cannot be used with --regex, disabling --record\n";
+ unset( $options['record'] );
+ }
+ $this->regex = $options['regex'];
+ } else {
+ # Matches anything
+ $this->regex = '';
+ }
+
+ $this->setupRecorder( $options );
+ $this->keepUploads = isset( $options['keep-uploads'] );
+
+ if ( isset( $options['seed'] ) ) {
+ $this->fuzzSeed = intval( $options['seed'] ) - 1;
+ }
+
+ $this->runDisabled = isset( $options['run-disabled'] );
+
+ $this->hooks = array();
+ $this->functionHooks = array();
+ }
+
+ 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 );
+ } elseif ( isset( $options['upload'] ) ) {
+ $this->recorder = new RemoteTestRecorder( $this );
+ } else {
+ $this->recorder = new TestRecorder( $this );
+ }
+ }
+
+ /**
+ * Remove last character if it is a newline
+ */
+ public function chomp( $s ) {
+ if ( substr( $s, -1 ) === "\n" ) {
+ return substr( $s, 0, -1 );
+ }
+ else {
+ return $s;
+ }
+ }
+
+ /**
+ * Run a fuzz test series
+ * Draw input from a set of test files
+ */
+ function fuzzTest( $filenames ) {
+ $GLOBALS['wgContLang'] = Language::factory( 'en' );
+ $dict = $this->getFuzzInput( $filenames );
+ $dictSize = strlen( $dict );
+ $logMaxLength = log( $this->maxFuzzTestLength );
+ $this->setupDatabase();
+ ini_set( 'memory_limit', $this->memoryLimit * 1048576 );
+
+ $numTotal = 0;
+ $numSuccess = 0;
+ $user = new User;
+ $opts = ParserOptions::newFromUser( $user );
+ $title = Title::makeTitle( NS_MAIN, 'Parser_test' );
+
+ while ( true ) {
+ // Generate test input
+ mt_srand( ++$this->fuzzSeed );
+ $totalLength = mt_rand( 1, $this->maxFuzzTestLength );
+ $input = '';
+
+ while ( strlen( $input ) < $totalLength ) {
+ $logHairLength = mt_rand( 0, 1000000 ) / 1000000 * $logMaxLength;
+ $hairLength = min( intval( exp( $logHairLength ) ), $dictSize );
+ $offset = mt_rand( 0, $dictSize - $hairLength );
+ $input .= substr( $dict, $offset, $hairLength );
+ }
+
+ $this->setupGlobals();
+ $parser = $this->getParser();
+
+ // Run the test
+ try {
+ $parser->parse( $input, $title, $opts );
+ $fail = false;
+ } catch ( Exception $exception ) {
+ $fail = true;
+ }
+
+ if ( $fail ) {
+ echo "Test failed with seed {$this->fuzzSeed}\n";
+ echo "Input:\n";
+ var_dump( $input );
+ echo "\n\n";
+ 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 ) {
+ $GLOBALS['wgContLang'] = Language::factory( 'en' );
+ $this->recorder->start();
+ $this->setupDatabase();
+ $ok = true;
+
+ foreach ( $filenames as $filename ) {
+ $tests = new TestFileIterator( $filename, $this );
+ $ok = $this->runTests( $tests ) && $ok;
+ }
+
+ $this->teardownDatabase();
+ $this->recorder->report();
+ $this->recorder->end();
+
+ return $ok;
+ }
+
+ function runTests( $tests ) {
+ $ok = true;
+
+ foreach ( $tests as $i => $t ) {
+ $result =
+ $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] );
+ $ok = $ok && $result;
+ $this->recorder->record( $t['test'], $result );
+ }
+
+ if ( $this->showProgress ) {
+ print "\n";
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Get a Parser object
+ */
+ function getParser( $preprocessor = null ) {
+ global $wgParserConf;
+
+ $class = $wgParserConf['class'];
+ $parser = new $class( array( 'preprocessorClass' => $preprocessor ) + $wgParserConf );
+
+ foreach ( $this->hooks as $tag => $callback ) {
+ $parser->setHook( $tag, $callback );
+ }
+
+ foreach ( $this->functionHooks as $tag => $bits ) {
+ list( $callback, $flags ) = $bits;
+ $parser->setFunctionHook( $tag, $callback, $flags );
+ }
+
+ wfRunHooks( 'ParserTestParser', array( &$parser ) );
+
+ return $parser;
+ }
+
+ /**
+ * Run a given wikitext input through a freshly-constructed wiki parser,
+ * and compare the output against the expected results.
+ * Prints status and explanatory messages to stdout.
+ *
+ * @param $desc String: test's description
+ * @param $input String: wikitext to try rendering
+ * @param $result String: result to output
+ * @param $opts Array: test's options
+ * @param $config String: overrides for global variables, one per line
+ * @return Boolean
+ */
+ public function runTest( $desc, $input, $result, $opts, $config ) {
+ if ( $this->showProgress ) {
+ $this->showTesting( $desc );
+ }
+
+ $opts = $this->parseOptions( $opts );
+ $this->setupGlobals( $opts, $config );
+
+ $user = new User();
+ $options = ParserOptions::newFromUser( $user );
+
+ if ( isset( $opts['title'] ) ) {
+ $titleText = $opts['title'];
+ }
+ else {
+ $titleText = 'Parser test';
+ }
+
+ $noxml = isset( $opts['noxml'] );
+ $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 );
+ } 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'] ) ) {
+ $linker = $user->getSkin();
+ $out = $linker->formatComment( $input, $title, $local );
+ } elseif ( isset( $opts['preload'] ) ) {
+ $out = $parser->getpreloadText( $input, $title, $options );
+ } else {
+ $output = $parser->parse( $input, $title, $options, true, true, 1337 );
+ $out = $output->getText();
+
+ if ( isset( $opts['showtitle'] ) ) {
+ if ( $output->getTitleText() ) {
+ $title = $output->getTitleText();
+ }
+
+ $out = "$title\n$out";
+ }
+
+ if ( isset( $opts['ill'] ) ) {
+ $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
+ } elseif ( isset( $opts['cat'] ) ) {
+ global $wgOut;
+
+ $wgOut->addCategoryLinks( $output->getCategories() );
+ $cats = $wgOut->getCategoryLinks();
+
+ if ( isset( $cats['normal'] ) ) {
+ $out = $this->tidy( implode( ' ', $cats['normal'] ) );
+ } else {
+ $out = '';
+ }
+ }
+
+ $result = $this->tidy( $result );
+ }
+
+
+ $this->teardownGlobals();
+
+ if ( $result === $out && ( $noxml === true || $this->wellFormed( $out ) ) ) {
+ return $this->showSuccess( $desc );
+ } else {
+ return $this->showFailure( $desc, $result, $out );
+ }
+ }
+
+ /**
+ * Use a regex to find out the value of an option
+ * @param $key String: name of option val to retrieve
+ * @param $opts Options array to look in
+ * @param $default Mixed: default value returned if not found
+ */
+ private static function getOptionValue( $key, $opts, $default ) {
+ $key = strtolower( $key );
+
+ if ( isset( $opts[$key] ) ) {
+ return $opts[$key];
+ } else {
+ return $default;
+ }
+ }
+
+ private function parseOptions( $instring ) {
+ $opts = array();
+ $lines = explode( "\n", $instring );
+ // 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 ) {
+ $match = 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 = '' ) {
+ global $wgDBtype;
+
+ # 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://localhost',
+ 'wgScript' => '/index.php',
+ 'wgScriptPath' => '/',
+ 'wgArticlePath' => '/wiki/$1',
+ 'wgActionPaths' => array(),
+ 'wgLocalFileRepo' => array(
+ 'class' => 'LocalRepo',
+ 'name' => 'local',
+ 'directory' => $this->uploadDir,
+ 'url' => 'http://example.com/images',
+ 'hashLevels' => 2,
+ 'transformVia404' => false,
+ ),
+ 'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
+ 'wgStyleSheetPath' => '/skins',
+ 'wgSitename' => 'MediaWiki',
+ 'wgServerName' => 'Britney-Spears',
+ 'wgLanguageCode' => $lang,
+ 'wgDBprefix' => $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_',
+ 'wgRawHtml' => isset( $opts['rawhtml'] ),
+ 'wgLang' => null,
+ 'wgContLang' => null,
+ 'wgNamespacesWithSubpages' => array( 0 => isset( $opts['subpage'] ) ),
+ 'wgMaxTocLevel' => $maxtoclevel,
+ 'wgCapitalLinks' => true,
+ 'wgNoFollowLinks' => true,
+ 'wgNoFollowDomainExceptions' => array(),
+ 'wgThumbnailScriptPath' => false,
+ 'wgUseImageResize' => false,
+ 'wgUseTeX' => isset( $opts['math'] ),
+ 'wgMathDirectory' => $this->uploadDir . '/math',
+ 'wgLocaltimezone' => 'UTC',
+ 'wgAllowExternalImages' => true,
+ 'wgUseTidy' => false,
+ 'wgDefaultLanguageVariant' => $variant,
+ 'wgVariantArticlePath' => false,
+ 'wgGroupPermissions' => array( '*' => array(
+ 'createaccount' => true,
+ 'read' => true,
+ 'edit' => true,
+ 'createpage' => true,
+ 'createtalk' => true,
+ ) ),
+ 'wgNamespaceProtection' => array( NS_MEDIAWIKI => 'editinterface' ),
+ 'wgDefaultExternalStore' => array(),
+ 'wgForeignFileRepos' => array(),
+ 'wgLinkHolderBatchSize' => $linkHolderBatchSize,
+ 'wgExperimentalHtmlIds' => false,
+ 'wgExternalLinkTarget' => false,
+ 'wgAlwaysUseTidy' => false,
+ 'wgHtml5' => true,
+ 'wgWellFormedXml' => true,
+ 'wgAllowMicrodataAttributes' => true,
+ );
+
+ if ( $config ) {
+ $configLines = explode( "\n", $config );
+
+ foreach ( $configLines as $line ) {
+ list( $var, $value ) = explode( '=', $line, 2 );
+
+ $settings[$var] = eval( "return $value;" );
+ }
+ }
+
+ $this->savedGlobals = array();
+
+ foreach ( $settings as $var => $val ) {
+ if ( array_key_exists( $var, $GLOBALS ) ) {
+ $this->savedGlobals[$var] = $GLOBALS[$var];
+ }
+
+ $GLOBALS[$var] = $val;
+ }
+
+ $langObj = Language::factory( $lang );
+ $GLOBALS['wgLang'] = $langObj;
+ $GLOBALS['wgContLang'] = $langObj;
+ $GLOBALS['wgMemc'] = new FakeMemCachedClient;
+ $GLOBALS['wgOut'] = new OutputPage;
+
+ global $wgHooks;
+
+ $wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
+ $wgHooks['ParserTestParser'][] = 'ParserTestStaticParserHook::setup';
+ $wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
+
+ MagicWord::clearCache();
+
+ global $wgUser;
+ $wgUser = new User();
+ }
+
+ /**
+ * List of temporary tables to create, without prefix.
+ * Some of these probably aren't necessary.
+ */
+ private function listTables() {
+ global $wgDBtype;
+
+ $tables = array( 'user', 'user_properties', 'page', 'page_restrictions',
+ 'protected_titles', 'revision', 'text', 'pagelinks', 'imagelinks',
+ 'categorylinks', 'templatelinks', 'externallinks', 'langlinks', 'iwlinks',
+ 'site_stats', 'hitcounter', 'ipblocks', 'image', 'oldimage',
+ 'recentchanges', 'watchlist', 'math', 'interwiki', 'logging',
+ 'querycache', 'objectcache', 'job', 'l10n_cache', 'redirect', 'querycachetwo',
+ 'archive', 'user_groups', 'page_props', 'category', 'msg_resource', 'msg_resource_links'
+ );
+
+ if ( in_array( $wgDBtype, array( 'mysql', 'sqlite' ) ) )
+ 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, $wgDBtype;
+
+ if ( $this->databaseSetupDone ) {
+ return;
+ }
+
+ if ( $wgDBprefix === 'parsertest_' || ( $wgDBtype == '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?).
+ # If it fails, $wgCaches[CACHE_DB] = new HashBagOStuff(); should work around it.
+
+ # CREATE TEMPORARY TABLE breaks if there is more than one server
+ if ( wfGetLB()->getServerCount() != 1 ) {
+ $this->useTemporaryTables = false;
+ }
+
+ $temporary = $this->useTemporaryTables || $wgDBtype == 'postgres';
+
+ $db = wfGetDB( DB_MASTER );
+ $tables = $this->listTables();
+
+ foreach ( $tables as $tbl ) {
+ # Clean up from previous aborted run. So that table escaping
+ # works correctly across DB engines, we need to change the pre-
+ # fix back and forth so tableName() works right.
+ $this->changePrefix( $this->oldTablePrefix );
+ $oldTableName = $db->tableName( $tbl );
+ $this->changePrefix( $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_' );
+ $newTableName = $db->tableName( $tbl );
+
+ if ( $wgDBtype == 'mysql' ) {
+ $db->query( "DROP TABLE IF EXISTS $newTableName" );
+ } elseif ( in_array( $wgDBtype, array( 'postgres', 'oracle' ) ) ) {
+ /* DROPs wouldn't work due to Foreign Key Constraints (bug 14990, r58669)
+ * Use "DROP TABLE IF EXISTS $newTableName CASCADE" for postgres? That
+ * syntax would also work for mysql.
+ */
+ } elseif ( $db->tableExists( $tbl ) ) {
+ $db->query( "DROP TABLE $newTableName" );
+ }
+
+ # Create new table
+ $db->duplicateTableStructure( $oldTableName, $newTableName, $temporary );
+ }
+
+ if ( $wgDBtype == 'oracle' )
+ $db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+
+ $this->changePrefix( $wgDBtype != 'oracle' ? 'parsertest_' : 'pt_' );
+
+ # Hack: insert a few Wikipedia in-project interwiki prefixes,
+ # for testing inter-language links
+ $db->insert( 'interwiki', array(
+ array( 'iw_prefix' => 'wikipedia',
+ 'iw_url' => 'http://en.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ),
+ array( 'iw_prefix' => 'meatball',
+ 'iw_url' => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 0 ),
+ array( 'iw_prefix' => 'zh',
+ 'iw_url' => 'http://zh.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'es',
+ 'iw_url' => 'http://es.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'fr',
+ 'iw_url' => 'http://fr.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ),
+ array( 'iw_prefix' => 'ru',
+ 'iw_url' => 'http://ru.wikipedia.org/wiki/$1',
+ 'iw_api' => '',
+ 'iw_wikiid' => '',
+ 'iw_local' => 1 ),
+ ) );
+
+
+ if ( $wgDBtype == 'oracle' ) {
+ # Insert 0 user to prevent FK violations
+
+ # Anonymous user
+ $db->insert( 'user', array(
+ 'user_id' => 0,
+ 'user_name' => 'Anonymous' ) );
+ }
+
+ # Update certain things in site_stats
+ $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();
+
+ # Make a new message cache
+ global $wgMessageCache, $wgMemc;
+ $wgMessageCache = new MessageCache( $wgMemc, true, 3600 );
+
+ $this->uploadDir = $this->setupUploadDir();
+ $user = User::createNew( 'WikiSysop' );
+ $image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
+ $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array(
+ 'size' => 12345,
+ 'width' => 1941,
+ 'height' => 220,
+ 'bits' => 24,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/jpeg',
+ 'metadata' => serialize( array() ),
+ 'sha1' => sha1( '' ),
+ 'fileExists' => true
+ ), $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' => sha1( '' ),
+ 'fileExists' => true
+ ), $db->timestamp( '20010115123500' ), $user );
+ }
+
+ /**
+ * Change the table prefix on all open DB connections/
+ */
+ protected function changePrefix( $prefix ) {
+ global $wgDBprefix;
+ wfGetLBFactory()->forEachLB( array( $this, 'changeLBPrefix' ), array( $prefix ) );
+ $wgDBprefix = $prefix;
+ }
+
+ public function changeLBPrefix( $lb, $prefix ) {
+ $lb->forEachOpenConnection( array( $this, 'changeDBPrefix' ), array( $prefix ) );
+ }
+
+ public function changeDBPrefix( $db, $prefix ) {
+ $db->tablePrefix( $prefix );
+ }
+
+ public function teardownDatabase() {
+ global $wgDBtype;
+
+ if ( !$this->databaseSetupDone ) {
+ return;
+ }
+ $this->teardownUploadDir( $this->uploadDir );
+
+ $this->changePrefix( $this->oldTablePrefix );
+ $this->databaseSetupDone = false;
+
+ if ( $this->useTemporaryTables ) {
+ # Don't need to do anything
+ return;
+ }
+
+ $tables = $this->listTables();
+ $db = wfGetDB( DB_MASTER );
+
+ foreach ( $tables as $table ) {
+ $sql = $wgDBtype == 'oracle' ? "DROP TABLE pt_$table DROP CONSTRAINTS" : "DROP TABLE `parsertest_$table`";
+ $db->query( $sql );
+ }
+
+ if ( $wgDBtype == 'oracle' )
+ $db->query( 'BEGIN FILL_WIKI_INFO; END;' );
+ }
+
+ /**
+ * 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' );
+ copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" );
+ wfMkdirParents( $dir . '/0/09' );
+ copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" );
+
+ return $dir;
+ }
+
+ /**
+ * Restore default values and perform any necessary clean-up
+ * after each test runs.
+ */
+ private function teardownGlobals() {
+ RepoGroup::destroySingleton();
+ LinkCache::singleton()->clear();
+
+ foreach ( $this->savedGlobals as $var => $val ) {
+ $GLOBALS[$var] = $val;
+ }
+ }
+
+ /**
+ * Remove the dummy uploads directory
+ */
+ private function teardownUploadDir( $dir ) {
+ if ( $this->keepUploads ) {
+ return;
+ }
+
+ // delete the files first, then the dirs.
+ self::deleteFiles(
+ array (
+ "$dir/3/3a/Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
+ "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
+
+ "$dir/0/09/Bad.jpg",
+
+ "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
+ )
+ );
+
+ self::deleteDirs(
+ array (
+ "$dir/3/3a",
+ "$dir/3",
+ "$dir/thumb/6/65",
+ "$dir/thumb/6",
+ "$dir/thumb/3/3a/Foobar.jpg",
+ "$dir/thumb/3/3a",
+ "$dir/thumb/3",
+
+ "$dir/0/09/",
+ "$dir/0/",
+ "$dir/thumb",
+ "$dir/math/f/a/5",
+ "$dir/math/f/a",
+ "$dir/math/f",
+ "$dir/math",
+ "$dir",
+ )
+ );
+ }
+
+ /**
+ * Delete the specified files, if they exist.
+ * @param $files Array: full paths to files to delete.
+ */
+ private static function deleteFiles( $files ) {
+ foreach ( $files as $file ) {
+ if ( file_exists( $file ) ) {
+ unlink( $file );
+ }
+ }
+ }
+
+ /**
+ * Delete the specified directories, if they exist. Must be empty.
+ * @param $dirs Array: full paths to directories to delete.
+ */
+ private static function deleteDirs( $dirs ) {
+ foreach ( $dirs as $dir ) {
+ if ( is_dir( $dir ) ) {
+ rmdir( $dir );
+ }
+ }
+ }
+
+ /**
+ * "Running test $desc..."
+ */
+ protected function showTesting( $desc ) {
+ print "Running test $desc... ";
+ }
+
+ /**
+ * Print a happy success message.
+ *
+ * @param $desc String: the test name
+ * @return Boolean
+ */
+ protected function showSuccess( $desc ) {
+ if ( $this->showProgress ) {
+ print $this->term->color( '1;32' ) . 'PASSED' . $this->term->reset() . "\n";
+ }
+
+ return true;
+ }
+
+ /**
+ * Print a failure message and provide some explanatory output
+ * about what went wrong if so configured.
+ *
+ * @param $desc String: the test name
+ * @param $result String: expected HTML output
+ * @param $html String: actual HTML output
+ * @return Boolean
+ */
+ protected function showFailure( $desc, $result, $html ) {
+ if ( $this->showFailure ) {
+ if ( !$this->showProgress ) {
+ # In quiet mode we didn't show the 'Testing' message before the
+ # test, in case it succeeded. Show it now:
+ $this->showTesting( $desc );
+ }
+
+ print $this->term->color( '31' ) . 'FAILED!' . $this->term->reset() . "\n";
+
+ if ( $this->showOutput ) {
+ print "--- Expected ---\n$result\n--- Actual ---\n$html\n";
+ }
+
+ if ( $this->showDiffs ) {
+ print $this->quickDiff( $result, $html );
+ if ( !$this->wellFormed( $html ) ) {
+ print "XML error: $this->mXmlError\n";
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Run given strings through a diff and return the (colorized) output.
+ * Requires writable /tmp directory and a 'diff' command in the PATH.
+ *
+ * @param $input String
+ * @param $output String
+ * @param $inFileTail String: tailing for the input file name
+ * @param $outFileTail String: tailing for the output file name
+ * @return String
+ */
+ protected function quickDiff( $input, $output, $inFileTail = 'expected', $outFileTail = 'actual' ) {
+ $prefix = wfTempDir() . "/mwParser-" . mt_rand();
+
+ $infile = "$prefix-$inFileTail";
+ $this->dumpToFile( $input, $infile );
+
+ $outfile = "$prefix-$outFileTail";
+ $this->dumpToFile( $output, $outfile );
+
+ $diff = `diff -au $infile $outfile`;
+ 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
+ */
+ public function addArticle( $name, $text, $line ) {
+ global $wgCapitalLinks;
+ $oldCapitalLinks = $wgCapitalLinks;
+ $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637
+
+ $title = Title::newFromText( $name );
+
+ if ( is_null( $title ) ) {
+ wfDie( "invalid title at line $line\n" );
+ }
+
+ $aid = $title->getArticleID( GAID_FOR_UPDATE );
+
+ if ( $aid != 0 ) {
+ wfDie( "duplicate article '$name' at line $line\n" );
+ }
+
+ $art = new Article( $title );
+ $art->insertNewArticle( $text, '', false, false );
+
+ $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
+ * @static
+ */
+ 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;
+ return true;
+ }
+}
--- /dev/null
+# MediaWiki Parser test cases
+# Some taken from http://meta.wikimedia.org/wiki/Parser_testing
+# All (C) their respective authors and released under the GPL
+#
+# The syntax should be fairly self-explanatory.
+#
+# Currently supported test options:
+# One of the following three:
+#
+# (default) generate HTML output
+# pst apply pre-save transform
+# msg apply message transform
+#
+# Plus any combination of these:
+#
+# cat add category links
+# ill add inter-language links
+# subpage enable subpages (disabled by default)
+# noxml don't check for XML well formdness
+# title=[[XXX]] run test using article title XXX
+# language=XXX set content language to XXX for this test
+# variant=XXX set the variant of language for this test (eg zh-tw)
+# disabled do not run test
+# showtitle make the first line the title
+# comment run through Linker::formatComment() instead of main parser
+# local format section links in edit comment text as local links
+#
+# For testing purposes, temporary articles can created:
+# !!article / NAMESPACE:TITLE / !!text / ARTICLE TEXT / !!endarticle
+# where '/' denotes a newline.
+
+# This is the standard article assumed to exist.
+!! article
+Main Page
+!! text
+blah blah
+!! endarticle
+
+!!article
+Template:Foo
+!!text
+FOO
+!!endarticle
+
+!! article
+Template:Blank
+!! text
+!! endarticle
+
+!! article
+Template:!
+!! text
+|
+!! endarticle
+
+!!article
+MediaWiki:bad image list
+!!text
+* [[File:Bad.jpg]] except [[Nasty page]]
+!!endarticle
+
+###
+### 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
+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
+
+###
+### <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
+
+
+###
+### Comments
+###
+!! test
+Comment test 1
+!! input
+<!-- comment 1 --> asdf
+<!-- comment 2 -->
+!! result
+<pre>asdf
+</pre>
+
+!! end
+
+!! test
+Comment test 2
+!! input
+asdf
+<!-- comment 1 -->
+jkl
+!! result
+<p>asdf
+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
+
+###
+### 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
+<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
+
+# Expected output in the following test is not really expected (there should be
+# <pre> in the output) -- it's only testing for well-formedness.
+!! test
+Bug 6200: Preformatted in <blockquote>
+!! input
+<blockquote>
+ Blah
+</blockquote>
+!! result
+<blockquote>
+ Blah
+</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
+<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
+
+###
+### 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 href="http://example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow">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 href="news:alt.wikipedia.rox" class="external free" rel="nofollow">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 href="news:alt.wikipedia.rox" class="external free" rel="nofollow">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 href="http://www.wikipedia2.org/" class="external text" rel="nofollow">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
+
+
+###
+### External links
+###
+!! test
+External links: non-bracketed
+!! input
+Non-bracketed: http://example.com
+!! result
+<p>Non-bracketed: <a href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external autonumber" rel="nofollow">[1]</a>
+Numbered: <a href="http://example.net" class="external autonumber" rel="nofollow">[2]</a>
+Numbered: <a href="http://example.com" class="external autonumber" rel="nofollow">[3]</a>
+</p>
+!!end
+
+!! test
+External links: specified text
+!! input
+Specified text: [http://example.com link]
+!! result
+<p>Specified text: <a href="http://example.com" class="external text" rel="nofollow">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 href="http://example.com" class="external text" rel="nofollow">link</a>s
+</p>
+!! end
+
+!! test
+External links: dollar sign in URL
+!! input
+http://example.com/1$2345
+!! result
+<p><a href="http://example.com/1$2345" class="external free" rel="nofollow">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 href="http://example.com/1$2345" class="external autonumber" rel="nofollow">[1]</a>
+</p>
+!!end
+
+!! test
+External links: open square bracket forbidden in URL (bug 4377)
+!! input
+http://example.com/1[2345
+!! result
+<p><a href="http://example.com/1" class="external free" rel="nofollow">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 href="http://example.com/1" class="external text" rel="nofollow">[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 href="http://example.com/" class="external text" rel="nofollow">''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 href="http://example.com/" class="external free" rel="nofollow">http://example.com/</a> first
+second]
+</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
+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 href="ftp://example.com/test.jpg" class="external free" rel="nofollow">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 href="http://example.com/thing" class="external free" rel="nofollow">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 href="http://example.com/1,2,3" class="external free" rel="nofollow">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 href="http://example.com/thing?url=http://example.com" class="external text" rel="nofollow">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 href="ftp://example.com?url=http://example.com" class="external text" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external text" rel="nofollow"><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 href="http://x&y" class="external free" rel="nofollow">http://x&y</a>
+</p>
+!! end
+
+!! test
+External links: encoded ampersand
+!! input
+Old & use: http://x&y
+!! result
+<p>Old & use: <a href="http://x&y" class="external free" rel="nofollow">http://x&y</a>
+</p>
+!! end
+
+!! test
+External links: encoded equals (bug 6102)
+!! input
+http://example.com/?foo=bar
+!! result
+<p><a href="http://example.com/?foo=bar" class="external free" rel="nofollow">http://example.com/?foo=bar</a>
+</p>
+!! end
+
+!! test
+External links: [raw ampersand]
+!! input
+Old & use: [http://x&y]
+!! result
+<p>Old & use: <a href="http://x&y" class="external autonumber" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: [encoded ampersand]
+!! input
+Old & use: [http://x&y]
+!! result
+<p>Old & use: <a href="http://x&y" class="external autonumber" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+External links: [encoded equals] (bug 6102)
+!! input
+[http://example.com/?foo=bar]
+!! result
+<p><a href="http://example.com/?foo=bar" class="external autonumber" rel="nofollow">[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 href="http://example.com/" class="external autonumber" rel="nofollow">[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 href="http://example.com/" class="external free" rel="nofollow">http://example.com/</a>
+</p>
+!! end
+
+!! test
+External links: www.jpeg.org (bug 554)
+!! input
+http://www.jpeg.org
+!!result
+<p><a href="http://www.jpeg.org" class="external free" rel="nofollow">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 href="http://www.unausa.org/newindex.asp?place=http://www.unausa.org/programs/mun.asp" class="external autonumber" rel="nofollow">[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 href="http://www.example.com/foo" class="external text" rel="nofollow">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 href="http://www.example.com/foo?=http://www.example.com/bar" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow"><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 href="http://www.example.com/" class="external text" rel="nofollow"><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 href="http://www.example.com/" class="external free" rel="nofollow">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 href="http://www.example.com/" class="external text" rel="nofollow">"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 href="http://www.example.com" class="external text" rel="nofollow">test</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 href="http://example.com" class="external text" rel="nofollow"></a><a href="/index.php?title=Wikilink&action=edit&redlink=1" class="new" title="Wikilink (page does not exist)">wikilink</a><a href="http://example.com" class="external text" rel="nofollow"> 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
+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 href="http://example.com" class="external text" rel="nofollow"><i>text</i></a>
+<a href="http://example.com" class="external text" rel="nofollow"><b>text</b></a>
+<i>Something </i><a href="http://example.com" class="external text" rel="nofollow"><i>in italic</i></a>
+<i>Something </i><a href="http://example.com" class="external text" rel="nofollow"><i>mixed</i><b>, even bold</b></a>
+<i><b>Now </b></i><a href="http://example.com" class="external text" rel="nofollow"><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 href="http://www.example.com/?title=AT%26T" class="external free" rel="nofollow">http://www.example.com/?title=AT%26T</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %26 in URL
+!! input
+http://www.example.com/?title=100%25_Bran
+!! result
+<p><a href="http://www.example.com/?title=100%25_Bran" class="external free" rel="nofollow">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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external free" rel="nofollow">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 href="http://www.example.com/?title=AT%26T" class="external autonumber" rel="nofollow">[1]</a>
+</p>
+!! end
+
+!! test
+Bug 4781, 5267: %26 in autonumber URL
+!! input
+[http://www.example.com/?title=100%25_Bran]
+!! result
+<p><a href="http://www.example.com/?title=100%25_Bran" class="external autonumber" rel="nofollow">[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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external autonumber" rel="nofollow">[1]</a>
+</p>
+!! end
+
+
+!! test
+Bug 4781: %26 in bracketed URL
+!! input
+[http://www.example.com/?title=AT%26T link]
+!! result
+<p><a href="http://www.example.com/?title=AT%26T" class="external text" rel="nofollow">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 href="http://www.example.com/?title=100%25_Bran" class="external text" rel="nofollow">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 href="http://www.example.com/?title=Ben-Hur_%281959_film%29" class="external text" rel="nofollow">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 href="http://example.com/" class="external text" rel="nofollow">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 href="http://example.com/" class="external text" rel="nofollow"><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 href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm" class="external text" rel="nofollow"><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
+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
+
+###
+### 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
+!! 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.
+!! 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>
+!! 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 minimun required by the spec, see:
+# http://www.w3.org/TR/xhtml-modularization/dtd_module_defs.html#a_module_Basic_Tables
+!! test
+A table with no data.
+!! input
+{||}
+!! result
+!! end
+
+# A table with nothing but a caption is invalid XHTML, we might want to render
+# this as <p>caption</p>
+!! test
+A table with nothing but a caption
+!! input
+{|
+|+ caption
+|}
+!! result
+<table>
+<caption> caption
+</caption><tr><td></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
+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
+Table rowspan
+!! input
+{| align=right 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 align="right" 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 href="ftp://%7Cx" class="external free" rel="nofollow">ftp://%7Cx</a></td>
+<td>]" onmouseover="alert(document.cookie)">test
+</td>
+</tr>
+</table>
+
+!! 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
+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
+
+!! 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
+
+!! 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 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
+Plain link to URL
+!! input
+[[http://www.example.com]]
+!! result
+<p>[<a href="http://www.example.com" class="external autonumber" rel="nofollow">[1]</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 href="http://www.example.com%7Can" class="external text" rel="nofollow">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
+
+
+###
+### 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
+
+!! 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
+
+
+##
+## XHTML tidiness
+###
+
+!! test
+<br> to <br />
+!! input
+1<br>2<br />3
+!! result
+<p>1<br />2<br />3
+</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 clear=left>
+<br clear=right>
+<br clear=all>
+!! result
+<p><br clear="left" />
+<br clear="right" />
+<br clear="all" />
+</p>
+!!end
+
+!! test
+Horizontal ruler (should it add that extra space?)
+!! input
+<hr>
+<hr >
+foo <hr
+> bar
+!! result
+<hr />
+<hr />
+foo <hr /> bar
+
+!! 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
+!! 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
+</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
+
+###
+### Magic Words
+###
+
+!! 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: {{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: {{CURRENTWEEK}} (@bug 4594)
+!! input
+{{CURRENTWEEK}}
+!! result
+<p>1
+</p>
+!! end
+
+!! test
+Magic Word: {{CURRENTYEAR}}
+!! input
+{{CURRENTYEAR}}
+!! result
+<p>1970
+</p>
+!! 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: {{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: {{NUMBEROFFILES}}
+!! input
+{{NUMBEROFFILES}}
+!! result
+<p>2
+</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: {{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: {{REVISIONID}}
+!! input
+{{REVISIONID}}
+!! result
+<p>1337
+</p>
+!! end
+
+!! test
+Magic Word: {{SCRIPTPATH}}
+!! input
+{{SCRIPTPATH}}
+!! result
+<p>/
+</p>
+!! end
+
+!! test
+Magic Word: {{SERVER}}
+!! input
+{{SERVER}}
+!! result
+<p><a href="http://localhost" class="external free" rel="nofollow">http://localhost</a>
+</p>
+!! end
+
+!! test
+Magic Word: {{SERVERNAME}}
+!! input
+{{SERVERNAME}}
+!! result
+<p>Britney-Spears
+</p>
+!! end
+
+!! test
+Magic Word: {{SITENAME}}
+!! input
+{{SITENAME}}
+!! result
+<p>MediaWiki
+</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 href="http://tools.ietf.org/html/rfc822" class="external mw-magiclink-rfc">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 href="http://www.ncbi.nlm.nih.gov/pubmed/1234?dopt=Abstract" class="external mw-magiclink-pmid">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
+
+!! 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
+
+
+!!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}}]]
+!! result
+<p><a href="/wiki/Main_Page" title="Main Page">Main Page</a>
+</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
+
+
+!! 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
+<onlyinclude> on a page
+!! input
+<onlyinclude>Foo</onlyinclude>bar
+!! result
+<p>Foobar
+</p>
+!! 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="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-1" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Includeonly_section">Includeonly section</span></h2>
+<h2><span class="editsection">[<a href="/index.php?title=Template:Includeonly_section&action=edit&section=T-2" title="Template:Includeonly section">edit</a>]</span> <span class="mw-headline" id="Section_T-1">Section T-1</span></h2>
+
+!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2>
+
+!! 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
+
+###
+### 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
+
+!! 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: comment containing math
+!! options
+pst
+!! input
+<!-- <math>data</math> -->
+!!result
+<!-- <math>data</math> -->
+!!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
+
+
+###
+### 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:foobarnonexistent}}
+!! result
+No such special page
+!! end
+
+###
+### Images
+###
+!! test
+Simple image
+!! 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
+Right-aligned image
+!! 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
+Simple image (using File: namespace, now canonical)
+!! 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
+Image with caption
+!! input
+[[Image: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 link parameter, wiki target
+!! input
+[[Image:foobar.jpg|link=Target page]]
+!! result
+<p><a href="/wiki/Target_page" title="Target page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+!! end
+
+!! test
+Image with link parameter, URL target
+!! input
+[[Image:foobar.jpg|link=http://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 empty link parameter
+!! input
+[[Image:foobar.jpg|link=]]
+!! result
+<p><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" />
+</p>
+!! end
+
+!! test
+Image with link parameter (wiki target) and unnamed parameter
+!! input
+[[Image:foobar.jpg|link=Target page|Title]]
+!! result
+<p><a href="/wiki/Target_page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+!! end
+
+!! test
+Image with link parameter (URL target) and unnamed parameter
+!! input
+[[Image:foobar.jpg|link=http://example.com/|Title]]
+!! result
+<p><a href="http://example.com/" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+!! end
+
+!! test
+Thumbnail image with link parameter
+!! 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/3/3a/Foobar.jpg" width="180" height="20" 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/3/3a/Foobar.jpg" width="180" height="20" 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><a href="http://example.com" class="external free" rel="nofollow">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/3/3a/Foobar.jpg" width="180" height="20" 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><a href="http://example.com" class="external free" rel="nofollow">http://example.com</a></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/3/3a/Foobar.jpg" width="180" height="20" 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><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/3/3a/Foobar.jpg" width="180" height="20" 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>This is <a href="http://tools.ietf.org/html/rfc12354" class="external mw-magiclink-rfc">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/3/3a/Foobar.jpg" width="180" height="20" 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>Please <a href="mailto:nobody@example.com" class="external free" rel="nofollow">mailto:nobody@example.com</a></div></div></div>
+
+!! end
+
+!! test
+BUG 1887: A <math> with a thumbnail- we don't render math in the parsertests by default,
+so math is not stripped and turns up as escaped <math> tags.
+!! input
+[[Image:foobar.jpg|thumb|<math>2+2</math>]]
+!! 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/3/3a/Foobar.jpg" width="180" height="20" 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><math>2+2</math></div></div></div>
+
+!! end
+
+!! test
+BUG 1887, part 2: A <math> with a thumbnail- math enabled
+!! options
+math
+!! input
+[[Image:foobar.jpg|thumb|<math>2+2</math>]]
+!! 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/3/3a/Foobar.jpg" width="180" height="20" 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><span class="texhtml">2 + 2</span></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/3/3a/Foobar.jpg" width="180" height="20" 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>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
+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/3/3a/Foobar.jpg" width="200" height="23" 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>This caption has <a href="irc://example.net" class="external text" rel="nofollow">irc</a> and <a href="https://example.com" class="external text" rel="nofollow">Secure</a> ext links in it.</div></div></div>
+
+!! 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
+
+
+###
+### 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
+
+!! 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
+
+###
+### Inter-language links
+###
+!! test
+Inter-language links
+!! options
+ill
+!! input
+[[es:Alimento]]
+[[fr:Nourriture]]
+[[zh:食品]]
+!! result
+es:Alimento fr:Nourriture zh:食品
+!! end
+
+###
+### Sections
+###
+!! test
+Basic section headings
+!! input
+== Headline 1 ==
+Some text
+
+==Headline 2==
+More
+===Smaller headline===
+Blah blah
+!! result
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2>
+<p>Some text
+</p>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2">Headline 2</span></h2>
+<p>More
+</p>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Smaller headline">edit</a>]</span> <span class="mw-headline" id="Smaller_headline">Smaller headline</span></h3>
+<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
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Headline 1">edit</a>]</span> <span class="mw-headline" id="Headline_1"> Headline 1 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Subheadline 1">edit</a>]</span> <span class="mw-headline" id="Subheadline_1"> Subheadline 1 </span></h3>
+<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level"> Skipping a level </span></h5>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Skipping a level">edit</a>]</span> <span class="mw-headline" id="Skipping_a_level_2"> Skipping a level </span></h6>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Headline 2">edit</a>]</span> <span class="mw-headline" id="Headline_2"> Headline 2 </span></h2>
+<p>Some text
+</p>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Another headline">edit</a>]</span> <span class="mw-headline" id="Another_headline">Another headline</span></h3>
+
+!! 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
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Level 1 Heading">edit</a>]</span> <span class="mw-headline" id="Level_1_Heading"> Level 1 Heading</span></h1>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Level 2 Heading">edit</a>]</span> <span class="mw-headline" id="Level_2_Heading"> Level 2 Heading</span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Level 3 Heading">edit</a>]</span> <span class="mw-headline" id="Level_3_Heading"> Level 3 Heading</span></h3>
+<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Level 4 Heading">edit</a>]</span> <span class="mw-headline" id="Level_4_Heading"> Level 4 Heading</span></h4>
+<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Level 5 Heading">edit</a>]</span> <span class="mw-headline" id="Level_5_Heading"> Level 5 Heading</span></h5>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: Level 6 Heading">edit</a>]</span> <span class="mw-headline" id="Level_6_Heading"> Level 6 Heading</span></h6>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=7" title="Edit section: = Level 7 Heading=">edit</a>]</span> <span class="mw-headline" id=".3D_Level_7_Heading.3D">= Level 7 Heading=</span></h6>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=8" title="Edit section: == Level 8 Heading==">edit</a>]</span> <span class="mw-headline" id=".3D.3D_Level_8_Heading.3D.3D">== Level 8 Heading==</span></h6>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=9" title="Edit section: === Level 9 Heading===">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D_Level_9_Heading.3D.3D.3D">=== Level 9 Heading===</span></h6>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=10" title="Edit section: ==== Level 10 Heading====">edit</a>]</span> <span class="mw-headline" id=".3D.3D.3D.3D_Level_10_Heading.3D.3D.3D.3D">==== Level 10 Heading====</span></h6>
+
+!! 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
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
+<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3>
+
+!! 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
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
+<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 1.1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1.1"> title 1.1.1 </span></h4>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: title 1.2">edit</a>]</span> <span class="mw-headline" id="title_1.2"> title 1.2 </span></h3>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: title 2.1">edit</a>]</span> <span class="mw-headline" id="title_2.1"> title 2.1 </span></h3>
+
+!! 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
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 1">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1">Section 1.1</span></h3>
+<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: Section 1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1">Section 1.1.1</span></h4>
+<h4><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: Section 1.1.1.1">edit</a>]</span> <span class="mw-headline" id="Section_1.1.1.1">Section 1.1.1.1</span></h4>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: Section 2">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2>
+
+!! end
+
+
+!! test
+Resolving duplicate section names
+!! input
+== Foo bar ==
+== Foo bar ==
+!! result
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar_2"> Foo bar </span></h2>
+
+!! end
+
+!! test
+Resolving duplicate section names with differing case (bug 10721)
+!! input
+== Foo bar ==
+== Foo Bar ==
+!! result
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Foo bar">edit</a>]</span> <span class="mw-headline" id="Foo_bar"> Foo bar </span></h2>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Foo Bar">edit</a>]</span> <span class="mw-headline" id="Foo_Bar_2"> Foo Bar </span></h2>
+
+!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section 0">edit</a>]</span> <span class="mw-headline" id="Section_0">Section 0</span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-1" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_1">Section 1</span></h3>
+<h2><span class="editsection">[<a href="/index.php?title=Template:Sections&action=edit&section=T-2" title="Template:Sections">edit</a>]</span> <span class="mw-headline" id="Section_2">Section 2</span></h2>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: Section 4">edit</a>]</span> <span class="mw-headline" id="Section_4">Section 4</span></h2>
+
+!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: Section with a link in it">edit</a>]</span> <span class="mw-headline" id="Section_with_a_link_in_it">Section with a <a href="/wiki/Main_Page" title="Main Page">link</a> in it</span></h2>
+
+!! end
+
+!! test
+TOC regression (bug 12077)
+!! input
+__TOC__
+== title 1 ==
+=== title 1.1 ===
+== title 2 ==
+!! result
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: title 1">edit</a>]</span> <span class="mw-headline" id="title_1"> title 1 </span></h2>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: title 1.1">edit</a>]</span> <span class="mw-headline" id="title_1.1"> title 1.1 </span></h3>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: title 2">edit</a>]</span> <span class="mw-headline" id="title_2"> title 2 </span></h2>
+
+!! end
+
+!! test
+BUG 1219 URL next to image (good)
+!! input
+http://example.com [[Image:foobar.jpg]]
+!! result
+<p><a href="http://example.com" class="external free" rel="nofollow">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 behaviour 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D">=</span></h1>
+<p>The line above must have a trailing space!
+</p>
+<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: =">edit</a>]</span> <span class="mw-headline" id=".3D_2">=</span></h1>
+<p>But just in case it doesn't...
+</p>
+!! end
+
+!! test
+BUG 1219 URL next to image (broken)
+!! input
+http://example.com[[Image:foobar.jpg]]
+!! result
+<p><a href="http://example.com" class="external free" rel="nofollow">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 href="http://en.wikinews.org/wiki/Wikinews:Workplace" class="external free" rel="nofollow">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
+
+
+!! 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 align="center" align="right">HTML rocks</div>
+!! result
+<div align="right">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 ALIGN="center">HTML ROCKS</DIV>
+!! result
+<div align="center">HTML ROCKS</div>
+
+!!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 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
+
+
+###
+### 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
+Math section safety when disabled
+!! input
+<math><script>alert(document.cookies);</script></math>
+!! result
+<p><math><script>alert(document.cookies);</script></math>
+</p>
+!! 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
+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 maintenance/parserTestsParserHook.php for the <tag> extension)
+###
+!! test
+Parser hook: empty input
+!! input
+<tag></tag>
+!! result
+<pre>
+string(0) ""
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements
+!! input
+<tag/>
+!! result
+<pre>
+NULL
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements (space before)
+!! input
+<tag />
+!! result
+<pre>
+NULL
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: basic input
+!! input
+<tag>input</tag>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+
+!! test
+Parser hook: case insensitive
+!! input
+<TAG>input</TAG>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+
+!! test
+Parser hook: case insensitive, redux
+!! input
+<TaG>input</TAg>
+!! result
+<pre>
+string(5) "input"
+array(0) {
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: nested tags
+!! options
+noxml
+!! input
+<tag><tag></tag></tag>
+!! result
+<pre>
+string(5) "<tag>"
+array(0) {
+}
+</pre></tag>
+
+!! end
+
+!! test
+Parser hook: basic arguments
+!! input
+<tag width=200 height = "100" depth = '50' square></tag>
+!! result
+<pre>
+string(0) ""
+array(4) {
+ ["width"]=>
+ string(3) "200"
+ ["height"]=>
+ string(3) "100"
+ ["depth"]=>
+ string(2) "50"
+ ["square"]=>
+ string(6) "square"
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: argument containing a forward slash (bug 5344)
+!! input
+<tag filename='/tmp/bla'></tag>
+!! result
+<pre>
+string(0) ""
+array(1) {
+ ["filename"]=>
+ string(8) "/tmp/bla"
+}
+</pre>
+
+!! end
+
+!! test
+Parser hook: empty input using terminated empty elements (bug 2374)
+!! input
+<tag foo=bar/>text
+!! result
+<pre>
+NULL
+array(1) {
+ ["foo"]=>
+ string(3) "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(4) {
+ ["width"]=>
+ string(3) "200"
+ ["height"]=>
+ string(3) "100"
+ ["depth"]=>
+ string(2) "50"
+ ["square"]=>
+ string(6) "square"
+}
+</pre>
+<p>other stuff
+</tag>
+</p>
+!! end
+
+###
+### (see maintenance/parserTestsStaticParserHook.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
+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 href="http://first/" class="external autonumber" rel="nofollow">[1]</a> <a href="http://second" class="external autonumber" rel="nofollow">[2]</a> <a href="ftp://ftp" class="external autonumber" rel="nofollow">[3]</a>
+</p><p><a href="ftp://inlineftp" class="external free" rel="nofollow">ftp://inlineftp</a>
+</p><p><a href="mailto:enclosed@mail.tld" class="external text" rel="nofollow">With target</a>
+</p><p><a href="mailto:enclosed@mail.tld" class="external autonumber" rel="nofollow">[4]</a>
+</p><p><a href="mailto:inline@mail.tld" class="external free" rel="nofollow">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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: onmouseover=">edit</a>]</span> <span class="mw-headline" id="onmouseover.3D"> onmouseover= </span></h2>
+http://<table id="toc" class="toc"><tr><td><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
+</ul>
+</td></tr></table>
+
+!! end
+
+!! test
+Fuzz testing: Parser14-table
+!! input
+==a==
+{| STYLE=__TOC__
+!! result
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: a">edit</a>]</span> <span class="mw-headline" id="a">a</span></h2>
+<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 href="irc://{{ftp://a" class="external free" rel="nofollow">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 href="http://===r:::https://b" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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 href="http://example.com" class="external free" rel="nofollow">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:1943px;">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
+<p><br />
+</p>
+<table border="0" 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
+<p><br />
+</p>
+<table border="0" id="mw-prefixindex-list-table"><tr><td><a href="/wiki/Xyzzyx" title="Xyzzyx">Xyzzyx</a></td></tr></table>
+<p><br />
+</p>
+<table border="0" 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 behaviour of bug 19910
+!! test
+Sectiion with all-equals
+!! options
+section=2
+!! input
+===
+The line above must have a trailing space
+=== <!--
+--> <!-- -->
+But just in case it doesn't...
+!! result
+=== <!--
+--> <!-- -->
+But just in case it doesn't...
+!! end
+
+!! test
+Section replacement test (section 0)
+!! options
+replace=0,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+xxx
+
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 1)
+!! options
+replace=1,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 2)
+!! options
+replace=2,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 3)
+!! options
+replace=3,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+xxx
+
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 4)
+!! options
+replace=4,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+xxx
+
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 5)
+!! options
+replace=5,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+xxx
+
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 6)
+!! options
+replace=6,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+xxx
+
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 7)
+!! options
+replace=7,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+xxx
+
+===bc===
+==c==
+===ca===
+!! end
+
+!! test
+Section replacement test (section 8)
+!! options
+replace=8,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+xxx
+
+==c==
+===ca===
+!!end
+
+!! test
+Section replacement test (section 9)
+!! options
+replace=9,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+xxx
+!! end
+
+!! test
+Section replacement test (section 10)
+!! options
+replace=10,"xxx"
+!! input
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+===ca===
+!! result
+start
+==a==
+===aa===
+====aaa====
+==b==
+===ba===
+===bb===
+====bba====
+===bc===
+==c==
+xxx
+!! end
+
+!! test
+Section replacement test with initial whitespace (bug 13728)
+!! options
+replace=2,"xxx"
+!! input
+ Preformatted initial line
+==a==
+===a===
+!! result
+ Preformatted initial line
+==a==
+xxx
+!! end
+
+
+!! test
+Section extraction, heading followed by pre with 20 spaces (bug 6398)
+!! options
+section=1
+!! input
+==a==
+ a
+!! result
+==a==
+ a
+!! end
+
+!! test
+Section extraction, heading followed by pre with 19 spaces (bug 6398 sanity check)
+!! options
+section=1
+!! input
+==a==
+ a
+!! result
+==a==
+ a
+!! end
+
+
+!! test
+Section extraction, <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 href="irc://%0Aa" class="external free" rel="nofollow">irc://%0Aa</a>
+</li></ul>
+</li></ul>
+
+!!end
+
+!! test
+5 quotes, code coverage +1 line
+!! input
+'''''
+!! result
+!! 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
+!! input
+* {{PAGENAME}}
+* {{BASEPAGENAME}}
+* {{SUBPAGENAME}}
+* {{SUBPAGENAMEE}}
+* {{BASEPAGENAME}}
+* {{BASEPAGENAMEE}}
+* {{TALKPAGENAME}}
+* {{TALKPAGENAMEE}}
+* {{SUBJECTPAGENAME}}
+* {{SUBJECTPAGENAMEE}}
+* {{NAMESPACEE}}
+* {{NAMESPACE}}
+* {{TALKSPACE}}
+* {{TALKSPACEE}}
+* {{SUBJECTSPACE}}
+* {{SUBJECTSPACEE}}
+* {{Dynamic|{{NUMBEROFUSERS}}|{{NUMBEROFPAGES}}|{{CURRENTVERSION}}|{{CONTENTLANGUAGE}}|{{DIRECTIONMARK}}|{{CURRENTTIMESTAMP}}|{{NUMBEROFARTICLES}}}}
+!! result
+<ul><li> Parser test
+</li><li> Parser test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li> Talk:Parser test
+</li><li> Talk:Parser_test
+</li><li> Parser test
+</li><li> Parser_test
+</li><li>
+</li><li>
+</li><li> Talk
+</li><li> Talk
+</li><li>
+</li><li>
+</li><li> <a href="/index.php?title=Template:Dynamic&action=edit&redlink=1" class="new" title="Template:Dynamic (page does not exist)">Template:Dynamic</a>
+</li></ul>
+
+!! 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
+<table class="gallery" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Image1.png</div>
+ <div class="gallerytext">
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Image2.gif</div>
+ <div class="gallerytext">
+<p>||||
+</p>
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Image3</div>
+ <div class="gallerytext">
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Image4</div>
+ <div class="gallerytext">
+<p>300px| centre
+</p>
+ </div>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Image5.svg</div>
+ <div class="gallerytext">
+<p><a href="http://///////" class="external free" rel="nofollow">http://///////</a>
+</p>
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">* image6</div>
+ <div class="gallerytext">
+ </div>
+ </div></td>
+ </tr>
+</table>
+
+!! end
+
+!! test
+Gallery (with options)
+!! input
+<gallery widths='60px' 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
+</gallery>
+!! result
+<table class="gallery" cellspacing="0" cellpadding="0">
+ <caption>Foo <a href="/wiki/Main_Page" title="Main Page">Main Page</a></caption>
+ <tr>
+ <td><div class="gallerybox" style="width: 95px;">
+ <div style="height: 52px;">Nonexistant.jpg</div>
+ <div class="gallerytext">
+<p>caption
+</p>
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 95px;">
+ <div style="height: 52px;">Nonexistant.jpg</div>
+ <div class="gallerytext">
+ </div>
+ </div></td>
+ </tr>
+ <tr>
+ <td><div class="gallerybox" style="width: 95px;">
+ <div class="thumb" style="padding: 19px 0; width: 90px;"><div style="margin-left: auto; margin-right: auto; width: 60px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="60" height="7" /></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></td>
+ <td><div class="gallerybox" style="width: 95px;">
+ <div class="thumb" style="padding: 19px 0; width: 90px;"><div style="margin-left: auto; margin-right: auto; width: 60px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="60" height="7" /></a></div></div>
+ <div class="gallerytext">
+ </div>
+ </div></td>
+ </tr>
+</table>
+
+!! 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
+<table class="gallery" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">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></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div style="height: 152px;">Nonexistant.jpg</div>
+ <div class="gallerytext">
+<p><a href="/wiki/File:Nonexistant.jpg" title="File:Nonexistant.jpg">Nonexistant.jpg</a><br />
+</p>
+ </div>
+ </div></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div class="thumb" style="padding: 66px 0; width: 150px;"><div style="margin-left: auto; margin-right: auto; width: 120px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/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></td>
+ <td><div class="gallerybox" style="width: 155px;">
+ <div class="thumb" style="padding: 66px 0; width: 150px;"><div style="margin-left: auto; margin-right: auto; width: 120px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/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></td>
+ </tr>
+</table>
+
+!! end
+
+!! test
+HTML Hex character encoding (spells the word "JavaScript")
+!! input
+JavaScript
+!! result
+<p>JavaScript
+</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 href="http://www.example.com" class="external text" rel="nofollow">example.com</a>
+</p>
+!! end
+
+!! test
+Double RFC
+!! input
+RFC RFC 1234
+!! result
+<p>RFC <a href="http://tools.ietf.org/html/rfc1234" class="external mw-magiclink-rfc">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 href="http://tools.ietf.org/html/rfc983" class="external mw-magiclink-rfc">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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="640" height="73" /></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/3/3a/Foobar.jpg" width="180" height="20" 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>An <a href="http://test/?param1=%7Cleft%7C&param2=%7Cx" class="external text" rel="nofollow">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
+rawhtml
+!! 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
+
+!! 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="editsection">[<a href="/index.php?title=MediaWiki:Fake&action=edit&section=T-1" title="MediaWiki:Fake">edit</a>]</span> <span class="mw-headline" id="header">header</span></h2>
+
+!! end
+
+
+!! test
+Out-of-order TOC heading levels
+!! input
+==2==
+======6======
+===3===
+=1=
+=====5=====
+==2==
+!! result
+<table id="toc" class="toc"><tr><td><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>
+</td></tr></table>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2">2</span></h2>
+<h6><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=2" title="Edit section: 6">edit</a>]</span> <span class="mw-headline" id="6">6</span></h6>
+<h3><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=3" title="Edit section: 3">edit</a>]</span> <span class="mw-headline" id="3">3</span></h3>
+<h1><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=4" title="Edit section: 1">edit</a>]</span> <span class="mw-headline" id="1">1</span></h1>
+<h5><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=5" title="Edit section: 5">edit</a>]</span> <span class="mw-headline" id="5">5</span></h5>
+<h2><span class="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=6" title="Edit section: 2">edit</a>]</span> <span class="mw-headline" id="2_2">2</span></h2>
+
+!! 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
+
+# Expected output in the following test is not necessarily expected (there
+# should probably be <p> tags inside the <blockquote> in the output) -- it's
+# only testing for well-formedness.
+!! test
+Bug 6200: blockquotes and paragraph formatting
+!! input
+<blockquote>
+foo
+</blockquote>
+
+bar
+
+ baz
+!! result
+<blockquote>
+foo
+</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
+
+
+###
+### 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
+
+
+!! 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
+
+
+!! 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="/index.php?title=Main_Page&variant=sr-ec" 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Уреди део: Naslov">уреди</a>]</span> <span class="mw-headline" id="-.7BNaslov.7D-"> Naslov </span></h2>
+
+!! 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
+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
+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
+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
+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
+
+!!article
+Template:Bullet
+!!text
+* Bar
+!!endarticle
+
+!! test
+Bug 529: Uncovered bullet
+!! input
+* Foo {{bullet}}
+!! result
+<ul><li> Foo
+</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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2>
+
+!! 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="editsection">[<a href="/index.php?title=Parser_test&action=edit&section=1" title="Edit section: heading">edit</a>]</span> <span class="mw-headline" id="heading">heading</span></h2>
+
+!! 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)
+!! options
+disabled
+!! 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)
+!! options
+disabled
+!! 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)
+!! options
+disabled
+!! 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)
+!! options
+disabled
+!! 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/3/3a/Foobar.jpg" width="180" height="20" 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>hello</div></div></div>
+
+!! end
+
+!! test
+Bug 15196: localised external link numbers
+!! options
+language=fa
+!! input
+[http://en.wikipedia.org/]
+!! result
+<p><a href="http://en.wikipedia.org/" class="external autonumber" rel="nofollow">[۱]</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
+Formatted date
+!! config
+wgUseDynamicDates=1
+!! input
+[[2009-03-24]]
+!! result
+<p><span class="mw-formatted-date" title="2009-03-24"><a href="/index.php?title=2009&action=edit&redlink=1" class="new" title="2009 (page does not exist)">2009</a>-<a href="/index.php?title=March_24&action=edit&redlink=1" class="new" title="March 24 (page does not exist)">03-24</a></span>
+</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
+Linked date with autoformatting disabled
+!! config
+wgUseDynamicDates=false
+!! input
+[[2009-03-24]]
+!! result
+<p><a href="/index.php?title=2009-03-24&action=edit&redlink=1" class="new" title="2009-03-24 (page does not exist)">2009-03-24</a>
+</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
+Spacing of numbers in formatted dates (linked)
+!! config
+wgUseDynamicDates=true
+!! input
+[[January 15]]
+!! result
+<p><span class="mw-formatted-date" title="01-15"><a href="/index.php?title=January_15&action=edit&redlink=1" class="new" title="January 15 (page does not exist)">January 15</a></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
+<span class="autocomment"><a href="/wiki/Main_Page#External_links" title="Main Page">→</a>External links: </span> removed bogus entries
+!!end
+
+!! test
+Edit comment with section link (local, eg in diff view)
+!! options
+comment local title=[[Main Page]]
+!! input
+/* External links */ removed bogus entries
+!! result
+<span class="autocomment"><a href="#External_links">→</a>External links: </span> removed bogus entries
+!!end
+
+!! test
+Edit comment with subpage link (bug 14080)
+!! options
+comment
+subpage
+title=[[Subpage test]]
+!! input
+Poked at a [[/subpage]] here...
+!! result
+Poked at a <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
+Space normalisation on autocomment (bug 22784)
+!! options
+comment
+title=[[Main Page]]
+!!input
+/* __hello__world__ */
+!! result
+<span class="autocomment"><a href="/wiki/Main_Page#hello_world" title="Main Page">→</a>__hello__world__</span>
+!! end
+
+!! test
+Bad images - basic functionality
+!! input
+[[File:Bad.jpg]]
+!! result
+!! end
+
+!! test
+Bad images - bug 16039: text after bad image disappears
+!! 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
+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
+
+
+TODO:
+more images
+more tables
+math
+character entities
+and much more
+Try for 100% code coverage
--- /dev/null
+<?php
+/**
+ * A basic extension that's used by the parser tests to test whether input and
+ * arguments are passed to extensions properly.
+ *
+ * Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
+ *
+ * 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 Maintenance
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+
+class ParserTestParserHook {
+
+ static function setup( &$parser ) {
+ $parser->setHook( 'tag', array( __CLASS__, 'hook' ) );
+
+ return true;
+ }
+
+ static function hook( $in, $argv ) {
+ ob_start();
+ var_dump(
+ $in,
+ $argv
+ );
+ $ret = ob_get_clean();
+
+ return "<pre>\n$ret</pre>";
+ }
+}
--- /dev/null
+<?php
+/**
+ * A basic extension that's used by the parser tests to test whether the parser
+ * calls extensions when they're called inside comments, it shouldn't do that
+ *
+ * Copyright © 2005, 2006 Ævar Arnfjörð Bjarmason
+ *
+ * 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 Maintenance
+ * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+ */
+
+class ParserTestStaticParserHook {
+ static function setup( &$parser ) {
+ $parser->setHook( 'statictag', array( __CLASS__, 'hook' ) );
+
+ return true;
+ }
+
+ static function hook( $in, $argv, $parser ) {
+ if ( ! count( $argv ) ) {
+ $parser->static_tag_buf = $in;
+ return '';
+ } else if ( count( $argv ) === 1 && isset( $argv['action'] )
+ && $argv['action'] === 'flush' && $in === null )
+ {
+ // Clear the buffer, we probably don't need to
+ if ( isset( $parser->static_tag_buf ) ) {
+ $tmp = $parser->static_tag_buf;
+ } else {
+ $tmp = '';
+ }
+ $parser->static_tag_buf = null;
+ return $tmp;
+ } else
+ // wtf?
+ return
+ "\nCall this extension as <statictag>string</statictag> or as" .
+ " <statictag action=flush/>, not in any other way.\n" .
+ "text: " . var_export( $in, true ) . "\n" .
+ "argv: " . var_export( $argv, true ) . "\n";
+ }
+}
--- /dev/null
+<?php
+# Copyright (C) 2004 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
+
+/**
+ * @file
+ * @ingroup Maintenance
+ */
+
+$options = array( 'quick', 'color', 'quiet', 'help', 'show-output', 'record', 'run-disabled' );
+$optionsWithArgs = array( 'regex', 'seed', 'setversion' );
+
+require_once( dirname( __FILE__ ) . '/../commandLine.inc' );
+
+if ( isset( $options['help'] ) ) {
+ echo <<<ENDS
+MediaWiki $wgVersion parser test suite
+Usage: php parserTests.php [options...]
+
+Options:
+ --quick Suppress diff output of failed tests
+ --quiet Suppress notification of passed tests (shows only failed tests)
+ --show-output Show expected and actual output
+ --color[=yes|no] Override terminal detection and force color output on or off
+ use wgCommandLineDarkBg = true; if your term is dark
+ --regex Only run tests whose descriptions which match given regex
+ --file=<testfile> Run test cases from a custom file instead of parserTests.txt
+ --record Record tests in database
+ --compare Compare with recorded results, without updating the database.
+ --setversion When using --record, set the version string to use (useful
+ with git-svn so that you can get the exact revision)
+ --keep-uploads Re-use the same upload directory for each test, don't delete it
+ --fuzz Do a fuzz test instead of a normal test
+ --seed <n> Start the fuzz test from the specified seed
+ --help Show this help message
+ --run-disabled run disabled tests
+ --upload Upload test results to remote wiki (per \$wgParserTestRemote)
+
+ENDS;
+ exit( 0 );
+}
+
+# Cases of weird db corruption were encountered when running tests on earlyish
+# versions of SQLite
+if ( $wgDBtype == 'sqlite' ) {
+ $db = wfGetDB( DB_MASTER );
+ $version = $db->getServerVersion();
+ if ( version_compare( $version, '3.6' ) < 0 ) {
+ die( "Parser tests require SQLite version 3.6 or later, you have $version\n" );
+ }
+}
+
+# There is a convention that the parser should never
+# refer to $wgTitle directly, but instead use the title
+# passed to it.
+$wgTitle = Title::newFromText( 'Parser test script do not use' );
+$tester = new ParserTest($options);
+
+if ( isset( $options['file'] ) ) {
+ $files = array( $options['file'] );
+} else {
+ // Default parser tests and any set from extensions or local config
+ $files = $wgParserTestFiles;
+}
+
+# Print out software version to assist with locating regressions
+$version = SpecialVersion::getVersion();
+echo( "This is MediaWiki version {$version}.\n\n" );
+
+if ( isset( $options['fuzz'] ) ) {
+ $tester->fuzzTest( $files );
+} else {
+ $ok = $tester->runTestsFromFiles( $files );
+ exit ( $ok ? 0 : 1 );
+}
$wgMemc = new FakeMemCachedClient;
$this->backend->setupDatabase();
- $iter = new TestFileIterator( "$IP/maintenance/parserTests.txt" );
+ $iter = new TestFileIterator( "$IP/maintenance/tests/parser/parserTests.txt" );
$iter->setParser( $this->backend );
$this->count = 0;
--- /dev/null
+<?php
+
+/**
+ * @ingroup Maintenance
+ *
+ * Set of classes to help with test output and such. Right now pretty specific
+ * to the parser tests but could be more useful one day :)
+ *
+ * @todo @fixme Make this more generic
+ */
+
+class AnsiTermColorer {
+ function __construct() {
+ }
+
+ /**
+ * Return ANSI terminal escape code for changing text attribs/color
+ *
+ * @param $color String: semicolon-separated list of attribute/color codes
+ * @return String
+ */
+ public function color( $color ) {
+ global $wgCommandLineDarkBg;
+
+ $light = $wgCommandLineDarkBg ? "1;" : "0;";
+
+ return "\x1b[{$light}{$color}m";
+ }
+
+ /**
+ * Return ANSI terminal escape code for restoring default text attributes
+ *
+ * @return String
+ */
+ public function reset() {
+ return $this->color( 0 );
+ }
+}
+
+/* A colour-less terminal */
+class DummyTermColorer {
+ public function color( $color ) {
+ return '';
+ }
+
+ public function reset() {
+ return '';
+ }
+}
+
+class TestRecorder {
+ var $parent;
+ var $term;
+
+ function __construct( $parent ) {
+ $this->parent = $parent;
+ $this->term = $parent->term;
+ }
+
+ function start() {
+ $this->total = 0;
+ $this->success = 0;
+ }
+
+ function record( $test, $result ) {
+ $this->total++;
+ $this->success += ( $result ? 1 : 0 );
+ }
+
+ function end() {
+ // dummy
+ }
+
+ function report() {
+ if ( $this->total > 0 ) {
+ $this->reportPercentage( $this->success, $this->total );
+ } else {
+ wfDie( "No tests found.\n" );
+ }
+ }
+
+ function reportPercentage( $success, $total ) {
+ $ratio = wfPercent( 100 * $success / $total );
+ print $this->term->color( 1 ) . "Passed $success of $total tests ($ratio)... ";
+
+ if ( $success == $total ) {
+ print $this->term->color( 32 ) . "ALL TESTS PASSED!";
+ } else {
+ $failed = $total - $success ;
+ print $this->term->color( 31 ) . "$failed tests failed!";
+ }
+
+ print $this->term->reset() . "\n";
+
+ return ( $success == $total );
+ }
+}
+
+class DbTestPreviewer extends TestRecorder {
+ protected $lb; // /< Database load balancer
+ protected $db; // /< Database connection to the main DB
+ protected $curRun; // /< run ID number for the current run
+ protected $prevRun; // /< run ID number for the previous run, if any
+ protected $results; // /< Result array
+
+ /**
+ * This should be called before the table prefix is changed
+ */
+ function __construct( $parent ) {
+ parent::__construct( $parent );
+
+ $this->lb = wfGetLBFactory()->newMainLB();
+ // This connection will have the wiki's table prefix, not parsertest_
+ $this->db = $this->lb->getConnection( DB_MASTER );
+ }
+
+ /**
+ * Set up result recording; insert a record for the run with the date
+ * and all that fun stuff
+ */
+ function start() {
+ parent::start();
+
+ if ( ! $this->db->tableExists( 'testrun' )
+ or ! $this->db->tableExists( 'testitem' ) )
+ {
+ print "WARNING> `testrun` table not found in database.\n";
+ $this->prevRun = false;
+ } else {
+ // We'll make comparisons against the previous run later...
+ $this->prevRun = $this->db->selectField( 'testrun', 'MAX(tr_id)' );
+ }
+
+ $this->results = array();
+ }
+
+ function record( $test, $result ) {
+ parent::record( $test, $result );
+ $this->results[$test] = $result;
+ }
+
+ function report() {
+ if ( $this->prevRun ) {
+ // f = fail, p = pass, n = nonexistent
+ // codes show before then after
+ $table = array(
+ 'fp' => 'previously failing test(s) now PASSING! :)',
+ 'pn' => 'previously PASSING test(s) removed o_O',
+ 'np' => 'new PASSING test(s) :)',
+
+ 'pf' => 'previously passing test(s) now FAILING! :(',
+ 'fn' => 'previously FAILING test(s) removed O_o',
+ 'nf' => 'new FAILING test(s) :(',
+ 'ff' => 'still FAILING test(s) :(',
+ );
+
+ $prevResults = array();
+
+ $res = $this->db->select( 'testitem', array( 'ti_name', 'ti_success' ),
+ array( 'ti_run' => $this->prevRun ), __METHOD__ );
+
+ foreach ( $res as $row ) {
+ if ( !$this->parent->regex
+ || preg_match( "/{$this->parent->regex}/i", $row->ti_name ) )
+ {
+ $prevResults[$row->ti_name] = $row->ti_success;
+ }
+ }
+
+ $combined = array_keys( $this->results + $prevResults );
+
+ # Determine breakdown by change type
+ $breakdown = array();
+ foreach ( $combined as $test ) {
+ if ( !isset( $prevResults[$test] ) ) {
+ $before = 'n';
+ } elseif ( $prevResults[$test] == 1 ) {
+ $before = 'p';
+ } else /* if ( $prevResults[$test] == 0 )*/ {
+ $before = 'f';
+ }
+
+ if ( !isset( $this->results[$test] ) ) {
+ $after = 'n';
+ } elseif ( $this->results[$test] == 1 ) {
+ $after = 'p';
+ } else /*if ( $this->results[$test] == 0 ) */ {
+ $after = 'f';
+ }
+
+ $code = $before . $after;
+
+ if ( isset( $table[$code] ) ) {
+ $breakdown[$code][$test] = $this->getTestStatusInfo( $test, $after );
+ }
+ }
+
+ # Write out results
+ foreach ( $table as $code => $label ) {
+ if ( !empty( $breakdown[$code] ) ) {
+ $count = count( $breakdown[$code] );
+ printf( "\n%4d %s\n", $count, $label );
+
+ foreach ( $breakdown[$code] as $differing_test_name => $statusInfo ) {
+ print " * $differing_test_name [$statusInfo]\n";
+ }
+ }
+ }
+ } else {
+ print "No previous test runs to compare against.\n";
+ }
+
+ print "\n";
+ parent::report();
+ }
+
+ /**
+ * Returns a string giving information about when a test last had a status change.
+ * Could help to track down when regressions were introduced, as distinct from tests
+ * which have never passed (which are more change requests than regressions).
+ */
+ private function getTestStatusInfo( $testname, $after ) {
+ // If we're looking at a test that has just been removed, then say when it first appeared.
+ if ( $after == 'n' ) {
+ $changedRun = $this->db->selectField ( 'testitem',
+ 'MIN(ti_run)',
+ array( 'ti_name' => $testname ),
+ __METHOD__ );
+ $appear = $this->db->selectRow ( 'testrun',
+ array( 'tr_date', 'tr_mw_version' ),
+ array( 'tr_id' => $changedRun ),
+ __METHOD__ );
+
+ return "First recorded appearance: "
+ . date( "d-M-Y H:i:s", strtotime ( $appear->tr_date ) )
+ . ", " . $appear->tr_mw_version;
+ }
+
+ // Otherwise, this test has previous recorded results.
+ // See when this test last had a different result to what we're seeing now.
+ $conds = array(
+ 'ti_name' => $testname,
+ 'ti_success' => ( $after == 'f' ? "1" : "0" ) );
+
+ if ( $this->curRun ) {
+ $conds[] = "ti_run != " . $this->db->addQuotes ( $this->curRun );
+ }
+
+ $changedRun = $this->db->selectField ( 'testitem', 'MAX(ti_run)', $conds, __METHOD__ );
+
+ // If no record of ever having had a different result.
+ if ( is_null ( $changedRun ) ) {
+ if ( $after == "f" ) {
+ return "Has never passed";
+ } else {
+ return "Has never failed";
+ }
+ }
+
+ // Otherwise, we're looking at a test whose status has changed.
+ // (i.e. it used to work, but now doesn't; or used to fail, but is now fixed.)
+ // In this situation, give as much info as we can as to when it changed status.
+ $pre = $this->db->selectRow ( 'testrun',
+ array( 'tr_date', 'tr_mw_version' ),
+ array( 'tr_id' => $changedRun ),
+ __METHOD__ );
+ $post = $this->db->selectRow ( 'testrun',
+ array( 'tr_date', 'tr_mw_version' ),
+ array( "tr_id > " . $this->db->addQuotes ( $changedRun ) ),
+ __METHOD__,
+ array( "LIMIT" => 1, "ORDER BY" => 'tr_id' )
+ );
+
+ if ( $post ) {
+ $postDate = date( "d-M-Y H:i:s", strtotime ( $post->tr_date ) ) . ", {$post->tr_mw_version}";
+ } else {
+ $postDate = 'now';
+ }
+
+ return ( $after == "f" ? "Introduced" : "Fixed" ) . " between "
+ . date( "d-M-Y H:i:s", strtotime ( $pre->tr_date ) ) . ", " . $pre->tr_mw_version
+ . " and $postDate";
+
+ }
+
+ /**
+ * Commit transaction and clean up for result recording
+ */
+ function end() {
+ $this->lb->commitMasterChanges();
+ $this->lb->closeAll();
+ parent::end();
+ }
+
+}
+
+class DbTestRecorder extends DbTestPreviewer {
+ var $version;
+
+ /**
+ * Set up result recording; insert a record for the run with the date
+ * and all that fun stuff
+ */
+ function start() {
+ global $wgDBtype;
+ $this->db->begin();
+
+ if ( ! $this->db->tableExists( 'testrun' )
+ or ! $this->db->tableExists( 'testitem' ) )
+ {
+ print "WARNING> `testrun` table not found in database. Trying to create table.\n";
+ if ( $wgDBtype === 'postgres' ) {
+ $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.postgres.sql' );
+ } elseif ( $wgDBtype === 'oracle' ) {
+ $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.ora.sql' );
+ } else {
+ $this->db->sourceFile( dirname( __FILE__ ) . '/testRunner.sql' );
+ }
+
+ echo "OK, resuming.\n";
+ }
+
+ parent::start();
+
+ $this->db->insert( 'testrun',
+ array(
+ 'tr_date' => $this->db->timestamp(),
+ 'tr_mw_version' => $this->version,
+ 'tr_php_version' => phpversion(),
+ 'tr_db_version' => $this->db->getServerVersion(),
+ 'tr_uname' => php_uname()
+ ),
+ __METHOD__ );
+ if ( $wgDBtype === 'postgres' ) {
+ $this->curRun = $this->db->currentSequenceValue( 'testrun_id_seq' );
+ } else {
+ $this->curRun = $this->db->insertId();
+ }
+ }
+
+ /**
+ * Record an individual test item's success or failure to the db
+ *
+ * @param $test String
+ * @param $result Boolean
+ */
+ function record( $test, $result ) {
+ parent::record( $test, $result );
+
+ $this->db->insert( 'testitem',
+ array(
+ 'ti_run' => $this->curRun,
+ 'ti_name' => $test,
+ 'ti_success' => $result ? 1 : 0,
+ ),
+ __METHOD__ );
+ }
+}
+
+class RemoteTestRecorder extends TestRecorder {
+ function start() {
+ parent::start();
+
+ $this->results = array();
+ $this->ping( 'running' );
+ }
+
+ function record( $test, $result ) {
+ parent::record( $test, $result );
+ $this->results[$test] = (bool)$result;
+ }
+
+ function end() {
+ $this->ping( 'complete', $this->results );
+ parent::end();
+ }
+
+ /**
+ * Inform a CodeReview instance that we've started or completed a test run...
+ *
+ * @param $status string: "running" - tell it we've started
+ * "complete" - provide test results array
+ * "abort" - something went horribly awry
+ * @param $results array of test name => true/false
+ */
+ function ping( $status, $results = false ) {
+ global $wgParserTestRemote, $IP;
+
+ $remote = $wgParserTestRemote;
+ $revId = SpecialVersion::getSvnRevision( $IP );
+ $jsonResults = FormatJson::encode( $results );
+
+ if ( !$remote ) {
+ print "Can't do remote upload without configuring \$wgParserTestRemote!\n";
+ exit( 1 );
+ }
+
+ // Generate a hash MAC to validate our credentials
+ $message = array(
+ $remote['repo'],
+ $remote['suite'],
+ $revId,
+ $status,
+ );
+
+ if ( $status == "complete" ) {
+ $message[] = $jsonResults;
+ }
+ $hmac = hash_hmac( "sha1", implode( "|", $message ), $remote['secret'] );
+
+ $postData = array(
+ 'action' => 'codetestupload',
+ 'format' => 'json',
+ 'repo' => $remote['repo'],
+ 'suite' => $remote['suite'],
+ 'rev' => $revId,
+ 'status' => $status,
+ 'hmac' => $hmac,
+ );
+
+ if ( $status == "complete" ) {
+ $postData['results'] = $jsonResults;
+ }
+
+ $response = $this->post( $remote['api-url'], $postData );
+
+ if ( $response === false ) {
+ print "CodeReview info upload failed to reach server.\n";
+ exit( 1 );
+ }
+
+ $responseData = FormatJson::decode( $response, true );
+
+ if ( !is_array( $responseData ) ) {
+ print "CodeReview API response not recognized...\n";
+ wfDebug( "Unrecognized CodeReview API response: $response\n" );
+ exit( 1 );
+ }
+
+ if ( isset( $responseData['error'] ) ) {
+ $code = $responseData['error']['code'];
+ $info = $responseData['error']['info'];
+ print "CodeReview info upload failed: $code $info\n";
+ exit( 1 );
+ }
+ }
+
+ function post( $url, $data ) {
+ return Http::post( $url, array( 'postData' => $data ) );
+ }
+}
+
+class TestFileIterator implements Iterator {
+ private $file;
+ private $fh;
+ private $parser;
+ private $index = 0;
+ private $test;
+ private $lineNum;
+ private $eof;
+
+ function __construct( $file, $parser = null ) {
+ global $IP;
+
+ $this->file = $file;
+ $this->fh = fopen( $this->file, "rt" );
+
+ if ( !$this->fh ) {
+ wfDie( "Couldn't open file '$file'\n" );
+ }
+
+ $this->parser = $parser;
+
+ if ( $this->parser ) {
+ $this->parser->showRunFile( wfRelativePath( $this->file, $IP ) );
+ }
+
+ $this->lineNum = $this->index = 0;
+ }
+
+ function setParser( ParserTest $parser ) {
+ $this->parser = $parser;
+ }
+
+ function rewind() {
+ if ( fseek( $this->fh, 0 ) ) {
+ wfDie( "Couldn't fseek to the start of '$this->file'\n" );
+ }
+
+ $this->index = -1;
+ $this->lineNum = 0;
+ $this->eof = false;
+ $this->next();
+
+ return true;
+ }
+
+ function current() {
+ return $this->test;
+ }
+
+ function key() {
+ return $this->index;
+ }
+
+ function next() {
+ if ( $this->readNextTest() ) {
+ $this->index++;
+ return true;
+ } else {
+ $this->eof = true;
+ }
+ }
+
+ function valid() {
+ return $this->eof != true;
+ }
+
+ function readNextTest() {
+ $data = array();
+ $section = null;
+
+ while ( false !== ( $line = fgets( $this->fh ) ) ) {
+ $this->lineNum++;
+ $matches = array();
+
+ if ( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
+ $section = strtolower( $matches[1] );
+
+ if ( $section == 'endarticle' ) {
+ if ( !isset( $data['text'] ) ) {
+ wfDie( "'endarticle' without 'text' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ if ( !isset( $data['article'] ) ) {
+ wfDie( "'endarticle' without 'article' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ if ( $this->parser ) {
+ $this->parser->addArticle( $this->parser->chomp( $data['article'] ), $this->parser->chomp( $data['text'] ),
+ $this->lineNum );
+ }
+
+ $data = array();
+ $section = null;
+
+ continue;
+ }
+
+ if ( $section == 'endhooks' ) {
+ if ( !isset( $data['hooks'] ) ) {
+ wfDie( "'endhooks' without 'hooks' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ foreach ( explode( "\n", $data['hooks'] ) as $line ) {
+ $line = trim( $line );
+
+ if ( $line ) {
+ if ( $this->parser && !$this->parser->requireHook( $line ) ) {
+ return false;
+ }
+ }
+ }
+
+ $data = array();
+ $section = null;
+
+ continue;
+ }
+
+ if ( $section == 'endfunctionhooks' ) {
+ if ( !isset( $data['functionhooks'] ) ) {
+ wfDie( "'endfunctionhooks' without 'functionhooks' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ foreach ( explode( "\n", $data['functionhooks'] ) as $line ) {
+ $line = trim( $line );
+
+ if ( $line ) {
+ if ( $this->parser && !$this->parser->requireFunctionHook( $line ) ) {
+ return false;
+ }
+ }
+ }
+
+ $data = array();
+ $section = null;
+
+ continue;
+ }
+
+ if ( $section == 'end' ) {
+ if ( !isset( $data['test'] ) ) {
+ wfDie( "'end' without 'test' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ if ( !isset( $data['input'] ) ) {
+ wfDie( "'end' without 'input' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ if ( !isset( $data['result'] ) ) {
+ wfDie( "'end' without 'result' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ if ( !isset( $data['options'] ) ) {
+ $data['options'] = '';
+ }
+
+ if ( !isset( $data['config'] ) )
+ $data['config'] = '';
+
+ if ( $this->parser
+ && ( ( preg_match( '/\\bdisabled\\b/i', $data['options'] ) && !$this->parser->runDisabled )
+ || !preg_match( "/" . $this->parser->regex . "/i", $data['test'] ) ) ) {
+ # disabled test
+ $data = array();
+ $section = null;
+
+ continue;
+ }
+
+ global $wgUseTeX;
+
+ if ( $this->parser &&
+ preg_match( '/\\bmath\\b/i', $data['options'] ) && !$wgUseTeX ) {
+ # don't run math tests if $wgUseTeX is set to false in LocalSettings
+ $data = array();
+ $section = null;
+
+ continue;
+ }
+
+ if ( $this->parser ) {
+ $this->test = array(
+ 'test' => $this->parser->chomp( $data['test'] ),
+ 'input' => $this->parser->chomp( $data['input'] ),
+ 'result' => $this->parser->chomp( $data['result'] ),
+ 'options' => $this->parser->chomp( $data['options'] ),
+ 'config' => $this->parser->chomp( $data['config'] ) );
+ } else {
+ $this->test['test'] = $data['test'];
+ }
+
+ return true;
+ }
+
+ if ( isset ( $data[$section] ) ) {
+ wfDie( "duplicate section '$section' at line {$this->lineNum} of $this->file\n" );
+ }
+
+ $data[$section] = '';
+
+ continue;
+ }
+
+ if ( $section ) {
+ $data[$section] .= $line;
+ }
+ }
+
+ return false;
+ }
+}