summaryrefslogtreecommitdiff
path: root/tests/phpunit/includes/parser
diff options
context:
space:
mode:
Diffstat (limited to 'tests/phpunit/includes/parser')
-rw-r--r--tests/phpunit/includes/parser/MagicVariableTest.php10
-rw-r--r--tests/phpunit/includes/parser/MediaWikiParserTest.php12
-rw-r--r--tests/phpunit/includes/parser/NewParserTest.php414
-rw-r--r--tests/phpunit/includes/parser/ParserHelpers.php136
-rw-r--r--tests/phpunit/includes/parser/ParserPreloadTest.php67
-rw-r--r--tests/phpunit/includes/parser/PreprocessorTest.php102
-rw-r--r--tests/phpunit/includes/parser/TagHooksTest.php (renamed from tests/phpunit/includes/parser/TagHooks.php)0
7 files changed, 379 insertions, 362 deletions
diff --git a/tests/phpunit/includes/parser/MagicVariableTest.php b/tests/phpunit/includes/parser/MagicVariableTest.php
index a47653e3..31645313 100644
--- a/tests/phpunit/includes/parser/MagicVariableTest.php
+++ b/tests/phpunit/includes/parser/MagicVariableTest.php
@@ -6,8 +6,8 @@
* As of february 2011, it only tests some revisions and date related
* magic variables.
*
- * @author Ashar Voultoiz
- * @copyright Copyright © 2011, Ashar Voultoiz
+ * @author Antoine Musso
+ * @copyright Copyright © 2011, Antoine Musso
* @file
*/
@@ -38,6 +38,12 @@ class MagicVariableTest extends MediaWikiTestCase {
# initialize parser output
$this->testParser->clearState();
+
+ # Needs a title to do magic word stuff
+ $title = Title::newFromText( 'Tests' );
+ $title->mRedirect = false; # Else it needs a db connection just to check if it's a redirect (when deciding the page language)
+
+ $this->testParser->setTitle( $title );
}
/** destroy parser (TODO: is it really neded?)*/
diff --git a/tests/phpunit/includes/parser/MediaWikiParserTest.php b/tests/phpunit/includes/parser/MediaWikiParserTest.php
index 18510d9a..816c017a 100644
--- a/tests/phpunit/includes/parser/MediaWikiParserTest.php
+++ b/tests/phpunit/includes/parser/MediaWikiParserTest.php
@@ -1,10 +1,8 @@
<?php
-
-require_once( dirname( __FILE__ ) . '/ParserHelpers.php' );
require_once( dirname( __FILE__ ) . '/NewParserTest.php' );
/**
- * The UnitTest must be either a class that inherits from PHPUnit_Framework_TestCase
+ * The UnitTest must be either a class that inherits from MediaWikiTestCase
* or a class that provides a public static suite() method which returns
* an PHPUnit_Framework_Test object
*
@@ -20,9 +18,13 @@ class MediaWikiParserTest {
foreach ( $wgParserTestFiles as $filename ) {
$testsName = basename( $filename, '.txt' );
- $className = /*ucfirst( basename( dirname( $filename ) ) ) .*/ ucfirst( basename( $filename, '.txt' ) );
+ /* This used to be ucfirst( basename( dirname( $filename ) ) )
+ * and then was ucfirst( basename( $filename, '.txt' )
+ * but that didn't work with names like foo.tests.txt
+ */
+ $className = str_replace( '.', '_', ucfirst( basename( $filename, '.txt' ) ) );
- eval( "/** @group Database\n@group Parser\n*/ class $className extends NewParserTest { protected \$file = \"" . addslashes( $filename ) . "\"; } " );
+ eval( "/** @group Database\n@group Parser\n*/ class $className extends NewParserTest { protected \$file = '" . strtr( $filename, array( "'" => "\\'", '\\' => '\\\\' ) ) . "'; } " );
$parserTester = new $className( $testsName );
$suite->addTestSuite( new ReflectionClass ( $parserTester ) );
diff --git a/tests/phpunit/includes/parser/NewParserTest.php b/tests/phpunit/includes/parser/NewParserTest.php
index f4d5f757..d1221ca8 100644
--- a/tests/phpunit/includes/parser/NewParserTest.php
+++ b/tests/phpunit/includes/parser/NewParserTest.php
@@ -8,13 +8,12 @@
* @group Stub
*/
class NewParserTest extends MediaWikiTestCase {
-
static protected $articles = array(); // Array of test articles defined by the tests
/* The dataProvider is run on a different instance than the test, so it must be static
* When running tests from several files, all tests will see all articles.
*/
-
- public $uploadDir;
+ static protected $backendToUse;
+
public $keepUploads = false;
public $runDisabled = false;
public $regex = '';
@@ -31,16 +30,12 @@ class NewParserTest extends MediaWikiTestCase {
public $memoryLimit = 50;
protected $file = false;
-
- /*function __construct($a = null,$b = array(),$c = null ) {
- parent::__construct($a,$b,$c);
- }*/
-
+
function setUp() {
global $wgContLang, $wgNamespaceProtection, $wgNamespaceAliases;
global $wgHooks, $IP;
$wgContLang = Language::factory( 'en' );
-
+
//Setup CLI arguments
if ( $this->getCliArg( 'regex=' ) ) {
$this->regex = $this->getCliArg( 'regex=' );
@@ -48,11 +43,11 @@ class NewParserTest extends MediaWikiTestCase {
# Matches anything
$this->regex = '';
}
-
+
$this->keepUploads = $this->getCliArg( 'keep-uploads' );
-
+
$tmpGlobals = array();
-
+
$tmpGlobals['wgScript'] = '/index.php';
$tmpGlobals['wgScriptPath'] = '/';
$tmpGlobals['wgArticlePath'] = '/wiki/$1';
@@ -60,15 +55,14 @@ class NewParserTest extends MediaWikiTestCase {
$tmpGlobals['wgStylePath'] = '/skins';
$tmpGlobals['wgThumbnailScriptPath'] = false;
$tmpGlobals['wgLocalFileRepo'] = array(
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'directory' => wfTempDir() . '/test-repo',
- 'url' => 'http://example.com/images',
- 'deletedDir' => wfTempDir() . '/test-repo/delete',
- 'hashLevels' => 2,
+ 'class' => 'LocalRepo',
+ 'name' => 'local',
+ 'url' => 'http://example.com/images',
+ 'hashLevels' => 2,
'transformVia404' => false,
+ 'backend' => 'local-backend'
);
-
+ $tmpGlobals['wgForeignFileRepos'] = array();
$tmpGlobals['wgEnableParserCache'] = false;
$tmpGlobals['wgHooks'] = $wgHooks;
$tmpGlobals['wgDeferredUpdateList'] = array();
@@ -79,16 +73,16 @@ class NewParserTest extends MediaWikiTestCase {
// $tmpGlobals['wgContLang'] = new StubContLang;
$tmpGlobals['wgUser'] = new User;
$context = new RequestContext();
- $tmpGlobals['wgLang'] = $context->getLang();
+ $tmpGlobals['wgLang'] = $context->getLanguage();
$tmpGlobals['wgOut'] = $context->getOutput();
$tmpGlobals['wgParser'] = new StubObject( 'wgParser', $GLOBALS['wgParserConf']['class'], array( $GLOBALS['wgParserConf'] ) );
- $tmpGlobals['wgRequest'] = new WebRequest;
+ $tmpGlobals['wgRequest'] = $context->getRequest();
if ( $GLOBALS['wgStyleDirectory'] === false ) {
$tmpGlobals['wgStyleDirectory'] = "$IP/skins";
}
-
-
+
+
foreach ( $tmpGlobals as $var => $val ) {
if ( array_key_exists( $var, $GLOBALS ) ) {
$this->savedInitialGlobals[$var] = $GLOBALS[$var];
@@ -96,31 +90,38 @@ class NewParserTest extends MediaWikiTestCase {
$GLOBALS[$var] = $val;
}
-
+
$this->savedWeirdGlobals['mw_namespace_protection'] = $wgNamespaceProtection[NS_MEDIAWIKI];
$this->savedWeirdGlobals['image_alias'] = $wgNamespaceAliases['Image'];
$this->savedWeirdGlobals['image_talk_alias'] = $wgNamespaceAliases['Image_talk'];
-
+
$wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';
$wgNamespaceAliases['Image'] = NS_FILE;
$wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;
-
}
-
+
public function tearDown() {
-
foreach ( $this->savedInitialGlobals as $var => $val ) {
$GLOBALS[$var] = $val;
}
-
+
global $wgNamespaceProtection, $wgNamespaceAliases;
-
+
$wgNamespaceProtection[NS_MEDIAWIKI] = $this->savedWeirdGlobals['mw_namespace_protection'];
$wgNamespaceAliases['Image'] = $this->savedWeirdGlobals['image_alias'];
$wgNamespaceAliases['Image_talk'] = $this->savedWeirdGlobals['image_talk_alias'];
+
+ // Restore backends
+ RepoGroup::destroySingleton();
+ FileBackendGroup::destroySingleton();
}
-
+
function addDBData() {
+ $this->tablesUsed[] = 'site_stats';
+ $this->tablesUsed[] = 'interwiki';
+ # disabled for performance
+ #$this->tablesUsed[] = 'image';
+
# Hack: insert a few Wikipedia in-project interwiki prefixes,
# for testing inter-language links
$this->db->insert( 'interwiki', array(
@@ -158,17 +159,14 @@ class NewParserTest extends MediaWikiTestCase {
* @todo Fixme! Why are we inserting duplicate data here? Shouldn't
* need this IGNORE or shouldn't need the insert at all.
*/
- ), __METHOD__, array( 'IGNORE' ) );
+ ), __METHOD__, array( 'IGNORE' )
+ );
# Update certain things in site_stats
- $this->db->insert( 'site_stats',
+ $this->db->insert( 'site_stats',
array( 'ss_row_id' => 1, 'ss_images' => 2, 'ss_good_articles' => 1 ),
- __METHOD__,
- /**
- * @todo Fixme! Same as above!
- */
- array( 'IGNORE' )
+ __METHOD__
);
# Reinitialise the LocalisationCache to match the database state
@@ -177,50 +175,66 @@ class NewParserTest extends MediaWikiTestCase {
# Clear the message cache
MessageCache::singleton()->clear();
- $this->uploadDir = $this->setupUploadDir();
-
$user = User::newFromId( 0 );
LinkCache::singleton()->clear(); # Avoids the odd failure at creating the nullRevision
-
+
+ # Upload DB table entries for files.
+ # We will upload the actual files later. Note that if anything causes LocalFile::load()
+ # to be triggered before then, it will break via maybeUpgrade() setting the fileExists
+ # member to false and storing it in cache.
$image = wfLocalFile( Title::makeTitle( NS_FILE, 'Foobar.jpg' ) );
- $image->recordUpload2( '', 'Upload of some lame file', 'Some lame file', array(
- 'size' => 12345,
- 'width' => 1941,
- 'height' => 220,
- 'bits' => 24,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( array() ),
- 'sha1' => wfBaseConvert( '', 16, 36, 31 ),
- 'fileExists' => true
- ), $this->db->timestamp( '20010115123500' ), $user );
+ if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) {
+ $image->recordUpload2(
+ '', // archive name
+ 'Upload of some lame file',
+ 'Some lame file',
+ array(
+ 'size' => 12345,
+ 'width' => 1941,
+ 'height' => 220,
+ 'bits' => 24,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/jpeg',
+ 'metadata' => serialize( array() ),
+ 'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+ 'fileExists' => true ),
+ $this->db->timestamp( '20010115123500' ), $user
+ );
+ }
# This image will be blacklisted in [[MediaWiki:Bad image list]]
$image = wfLocalFile( Title::makeTitle( NS_FILE, 'Bad.jpg' ) );
- $image->recordUpload2( '', 'zomgnotcensored', 'Borderline image', array(
- 'size' => 12345,
- 'width' => 320,
- 'height' => 240,
- 'bits' => 24,
- 'media_type' => MEDIATYPE_BITMAP,
- 'mime' => 'image/jpeg',
- 'metadata' => serialize( array() ),
- 'sha1' => wfBaseConvert( '', 16, 36, 31 ),
- 'fileExists' => true
- ), $this->db->timestamp( '20010115123500' ), $user );
-
+ if ( !$this->db->selectField( 'image', '1', array( 'img_name' => $image->getName() ) ) ) {
+ $image->recordUpload2(
+ '', // archive name
+ 'zomgnotcensored',
+ 'Borderline image',
+ array(
+ 'size' => 12345,
+ 'width' => 320,
+ 'height' => 240,
+ 'bits' => 24,
+ 'media_type' => MEDIATYPE_BITMAP,
+ 'mime' => 'image/jpeg',
+ 'metadata' => serialize( array() ),
+ 'sha1' => wfBaseConvert( '', 16, 36, 31 ),
+ 'fileExists' => true ),
+ $this->db->timestamp( '20010115123500' ), $user
+ );
+ }
}
-
-
-
-
+
+
+
+
//ParserTest setup/teardown functions
-
+
/**
* Set up the global variables for a consistent environment for each test.
* Ideally this should replace the global configuration entirely.
*/
protected function setupGlobals( $opts = '', $config = '' ) {
+ global $wgFileBackends;
# Find out values for some special options.
$lang =
self::getOptionValue( 'language', $opts, 'en' );
@@ -231,19 +245,48 @@ class NewParserTest extends MediaWikiTestCase {
$linkHolderBatchSize =
self::getOptionValue( 'wgLinkHolderBatchSize', $opts, 1000 );
+ $uploadDir = $this->getUploadDir();
+ if ( $this->getCliArg( 'use-filebackend=' ) ) {
+ if ( self::$backendToUse ) {
+ $backend = self::$backendToUse;
+ } else {
+ $name = $this->getCliArg( 'use-filebackend=' );
+ $useConfig = array();
+ foreach ( $wgFileBackends as $conf ) {
+ if ( $conf['name'] == $name ) {
+ $useConfig = $conf;
+ }
+ }
+ $useConfig['name'] = 'local-backend'; // swap name
+ $class = $conf['class'];
+ self::$backendToUse = new $class( $useConfig );
+ $backend = self::$backendToUse;
+ }
+ } else {
+ $backend = new FSFileBackend( array(
+ 'name' => 'local-backend',
+ 'lockManager' => 'nullLockManager',
+ 'containerPaths' => array(
+ 'local-public' => "$uploadDir",
+ 'local-thumb' => "$uploadDir/thumb",
+ )
+ ) );
+ }
+
$settings = array(
'wgServer' => 'http://Britney-Spears',
'wgScript' => '/index.php',
'wgScriptPath' => '/',
'wgArticlePath' => '/wiki/$1',
+ 'wgExtensionAssetsPath' => '/extensions',
'wgActionPaths' => array(),
'wgLocalFileRepo' => array(
- 'class' => 'LocalRepo',
- 'name' => 'local',
- 'directory' => $this->uploadDir,
- 'url' => 'http://example.com/images',
- 'hashLevels' => 2,
+ 'class' => 'LocalRepo',
+ 'name' => 'local',
+ 'url' => 'http://example.com/images',
+ 'hashLevels' => 2,
'transformVia404' => false,
+ 'backend' => $backend
),
'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
'wgStylePath' => '/skins',
@@ -262,7 +305,7 @@ class NewParserTest extends MediaWikiTestCase {
'wgThumbnailScriptPath' => false,
'wgUseImageResize' => false,
'wgUseTeX' => isset( $opts['math'] ),
- 'wgMathDirectory' => $this->uploadDir . '/math',
+ 'wgMathDirectory' => $uploadDir . '/math',
'wgLocaltimezone' => 'UTC',
'wgAllowExternalImages' => true,
'wgUseTidy' => false,
@@ -283,6 +326,7 @@ class NewParserTest extends MediaWikiTestCase {
'wgExternalLinkTarget' => false,
'wgAlwaysUseTidy' => false,
'wgHtml5' => true,
+ 'wgCleanupPresentationalAttributes' => true,
'wgWellFormedXml' => true,
'wgAllowMicrodataAttributes' => true,
'wgAdaptiveMessageCache' => true,
@@ -312,39 +356,41 @@ class NewParserTest extends MediaWikiTestCase {
$langObj = Language::factory( $lang );
$GLOBALS['wgContLang'] = $langObj;
$context = new RequestContext();
- $GLOBALS['wgLang'] = $context->getLang();
+ $GLOBALS['wgLang'] = $context->getLanguage();
$GLOBALS['wgMemc'] = new EmptyBagOStuff;
$GLOBALS['wgOut'] = $context->getOutput();
+ $GLOBALS['wgUser'] = $context->getUser();
global $wgHooks;
$wgHooks['ParserTestParser'][] = 'ParserTestParserHook::setup';
- $wgHooks['ParserTestParser'][] = 'ParserTestStaticParserHook::setup';
$wgHooks['ParserGetVariableValueTs'][] = 'ParserTest::getFakeTimestamp';
MagicWord::clearCache();
+ RepoGroup::destroySingleton();
+ FileBackendGroup::destroySingleton();
+
+ # Create dummy files in storage
+ $this->setupUploads();
# Publish the articles after we have the final language set
$this->publishTestArticles();
# The entries saved into RepoGroup cache with previous globals will be wrong.
RepoGroup::destroySingleton();
+ FileBackendGroup::destroySingleton();
MessageCache::singleton()->destroyInstance();
-
- global $wgUser;
- $wgUser = new User();
+
+ return $context;
}
/**
- * Create a dummy uploads directory which will contain a couple
- * of files in order to pass existence tests.
+ * Get an FS upload directory (only applies to FSFileBackend)
*
* @return String: the directory
*/
- protected function setupUploadDir() {
- global $IP;
-
+ protected function getUploadDir() {
if ( $this->keepUploads ) {
$dir = wfTempDir() . '/mwParser-images';
@@ -361,70 +407,67 @@ class NewParserTest extends MediaWikiTestCase {
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;
}
-
+
+ /**
+ * Create a dummy uploads directory which will contain a couple
+ * of files in order to pass existence tests.
+ *
+ * @return String: the directory
+ */
+ protected function setupUploads() {
+ global $IP;
+
+ $base = $this->getBaseDir();
+ $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
+ $backend->prepare( array( 'dir' => "$base/local-public/3/3a" ) );
+ $backend->store( array(
+ 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/3/3a/Foobar.jpg"
+ ) );
+ $backend->prepare( array( 'dir' => "$base/local-public/0/09" ) );
+ $backend->store( array(
+ 'src' => "$IP/skins/monobook/headbg.jpg", 'dst' => "$base/local-public/0/09/Bad.jpg"
+ ) );
+ }
+
/**
* Restore default values and perform any necessary clean-up
* after each test runs.
*/
protected function teardownGlobals() {
- RepoGroup::destroySingleton();
- LinkCache::singleton()->clear();
+ $this->teardownUploads();
foreach ( $this->savedGlobals as $var => $val ) {
$GLOBALS[$var] = $val;
}
-
- $this->teardownUploadDir( $this->uploadDir );
+
+ RepoGroup::destroySingleton();
+ LinkCache::singleton()->clear();
}
/**
* Remove the dummy uploads directory
*/
- private function teardownUploadDir( $dir ) {
+ private function teardownUploads() {
if ( $this->keepUploads ) {
return;
}
+ $base = $this->getBaseDir();
// 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",
+ "$base/local-public/3/3a/Foobar.jpg",
+ "$base/local-thumb/3/3a/Foobar.jpg/180px-Foobar.jpg",
+ "$base/local-thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
+ "$base/local-thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
+ "$base/local-thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
- "$dir/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
- )
- );
+ "$base/local-public/0/09/Bad.jpg",
+ "$base/local-thumb/0/09/Bad.jpg",
- self::deleteDirs(
- array (
- "$dir/3/3a",
- "$dir/3",
- "$dir/thumb/6/65",
- "$dir/thumb/6",
- "$dir/thumb/3/3a/Foobar.jpg",
- "$dir/thumb/3/3a",
- "$dir/thumb/3",
-
- "$dir/0/09/",
- "$dir/0/",
- "$dir/thumb",
- "$dir/math/f/a/5",
- "$dir/math/f/a",
- "$dir/math/f",
- "$dir/math",
- "$dir",
+ "$base/local-public/math/f/a/5/fa50b8b616463173474302ca3e63586b.png",
)
);
}
@@ -434,25 +477,24 @@ class NewParserTest extends MediaWikiTestCase {
* @param $files Array: full paths to files to delete.
*/
private static function deleteFiles( $files ) {
+ $backend = RepoGroup::singleton()->getLocalRepo()->getBackend();
foreach ( $files as $file ) {
- if ( file_exists( $file ) ) {
- unlink( $file );
+ $backend->delete( array( 'src' => $file ), array( 'force' => 1 ) );
+ }
+ foreach ( $files as $file ) {
+ $tmp = $file;
+ while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) {
+ if ( !$backend->clean( array( 'dir' => $tmp ) )->isOK() ) {
+ break;
+ }
}
}
}
- /**
- * 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 );
- }
- }
+ protected function getBaseDir() {
+ return 'mwstore://local-backend';
}
-
+
public function parserTestProvider() {
if ( $this->file === false ) {
global $wgParserTestFiles;
@@ -460,25 +502,29 @@ class NewParserTest extends MediaWikiTestCase {
}
return new TestFileIterator( $this->file, $this );
}
-
+
/**
* Set the file from whose tests will be run by this instance
*/
public function setParserTestFile( $filename ) {
$this->file = $filename;
}
-
+
/** @dataProvider parserTestProvider */
public function testParserTest( $desc, $input, $result, $opts, $config ) {
- if ( !preg_match( '/' . $this->regex . '/', $desc ) ) return; //$this->markTestSkipped( 'Filtered out by the user' );
+ if ( $this->regex != '' && !preg_match( '/' . $this->regex . '/', $desc ) ) {
+ $this->assertTrue( true ); // XXX: don't flood output with "test made no assertions"
+ //$this->markTestSkipped( 'Filtered out by the user' );
+ return;
+ }
wfDebug( "Running parser test: $desc\n" );
$opts = $this->parseOptions( $opts );
- $this->setupGlobals( $opts, $config );
+ $context = $this->setupGlobals( $opts, $config );
- $user = new User();
- $options = ParserOptions::newFromUser( $user );
+ $user = $context->getUser();
+ $options = ParserOptions::newFromContext( $context );
if ( isset( $opts['title'] ) ) {
$titleText = $opts['title'];
@@ -490,7 +536,7 @@ class NewParserTest extends MediaWikiTestCase {
$local = isset( $opts['local'] );
$preprocessor = isset( $opts['preprocessor'] ) ? $opts['preprocessor'] : null;
$parser = $this->getParser( $preprocessor );
-
+
$title = Title::newFromText( $titleText );
if ( isset( $opts['pst'] ) ) {
@@ -505,8 +551,7 @@ class NewParserTest extends MediaWikiTestCase {
$replace = $opts['replace'][1];
$out = $parser->replaceSection( $input, $section, $replace );
} elseif ( isset( $opts['comment'] ) ) {
- $linker = $user->getSkin();
- $out = $linker->formatComment( $input, $title, $local );
+ $out = Linker::formatComment( $input, $title, $local );
} elseif ( isset( $opts['preload'] ) ) {
$out = $parser->getpreloadText( $input, $title, $options );
} else {
@@ -524,10 +569,9 @@ class NewParserTest extends MediaWikiTestCase {
if ( isset( $opts['ill'] ) ) {
$out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
} elseif ( isset( $opts['cat'] ) ) {
- global $wgOut;
-
- $wgOut->addCategoryLinks( $output->getCategories() );
- $cats = $wgOut->getCategoryLinks();
+ $outputPage = $context->getOutput();
+ $outputPage->addCategoryLinks( $output->getCategories() );
+ $cats = $outputPage->getCategoryLinks();
if ( isset( $cats['normal'] ) ) {
$out = $this->tidy( implode( ' ', $cats['normal'] ) );
@@ -541,38 +585,41 @@ class NewParserTest extends MediaWikiTestCase {
}
$this->teardownGlobals();
-
+
$this->assertEquals( $result, $out, $desc );
}
-
+
/**
* Run a fuzz test series
* Draw input from a set of test files
+ *
+ * @todo @fixme Needs some work to not eat memory until the world explodes
+ *
+ * @group ParserFuzz
*/
function testFuzzTests() {
-
- $this->markTestIncomplete( "Somebody is serializing PDO objects, that's a no-no" );
-
global $wgParserTestFiles;
-
+
$files = $wgParserTestFiles;
-
+
if( $this->getCliArg( 'file=' ) ) {
$files = array( $this->getCliArg( 'file=' ) );
}
-
+
$dict = $this->getFuzzInput( $files );
$dictSize = strlen( $dict );
$logMaxLength = log( $this->maxFuzzTestLength );
+ ini_set( 'memory_limit', $this->memoryLimit * 1048576 );
+
$user = new User;
$opts = ParserOptions::newFromUser( $user );
$title = Title::makeTitle( NS_MAIN, 'Parser_test' );
$id = 1;
-
+
while ( true ) {
-
+
// Generate test input
mt_srand( ++$this->fuzzSeed );
$totalLength = mt_rand( 1, $this->maxFuzzTestLength );
@@ -594,7 +641,7 @@ class NewParserTest extends MediaWikiTestCase {
$this->assertTrue( true, "Test $id, fuzz seed {$this->fuzzSeed}" );
} catch ( Exception $exception ) {
$input_dump = sprintf( "string(%d) \"%s\"\n", strlen( $input ), $input );
-
+
$this->assertTrue( false, "Test $id, fuzz seed {$this->fuzzSeed}. \n\nInput: $input_dump\n\nError: {$exception->getMessage()}\n\nBacktrace: {$exception->getTraceAsString()}" );
}
@@ -611,18 +658,18 @@ class NewParserTest extends MediaWikiTestCase {
foreach ( $memStats as $name => $usage ) {
$ret .= "$name: $usage\n";
}
-
+
throw new MWException( $ret );
}
}
-
+
$id++;
-
+
}
}
//Various getter functions
-
+
/**
* Get an input dictionary from a set of parser test files
*/
@@ -640,7 +687,7 @@ class NewParserTest extends MediaWikiTestCase {
return $dict;
}
-
+
/**
* Get a memory usage breakdown
*/
@@ -675,7 +722,7 @@ class NewParserTest extends MediaWikiTestCase {
return $memStats;
}
-
+
/**
* Get a Parser object
*/
@@ -693,23 +740,20 @@ class NewParserTest extends MediaWikiTestCase {
//Various action functions
public function addArticle( $name, $text, $line ) {
- self::$articles[$name] = $text;
- }
-
+ self::$articles[$name] = array( $text, $line );
+ }
+
public function publishTestArticles() {
if ( empty( self::$articles ) ) {
return;
}
- foreach ( self::$articles as $name => $text ) {
- $title = Title::newFromText( $name );
-
- if ( $title->getArticleID( Title::GAID_FOR_UPDATE ) == 0 ) {
- ParserTest::addArticle( $name, $text );
- }
+ foreach ( self::$articles as $name => $info ) {
+ list( $text, $line ) = $info;
+ ParserTest::addArticle( $name, $text, $line, 'ignoreduplicate' );
}
}
-
+
/**
* Steal a callback function from the primary parser, save it for
* application to our scary parser. If the hook is not installed,
@@ -730,8 +774,8 @@ class NewParserTest extends MediaWikiTestCase {
return isset( $wgParser->mFunctionHooks[$name] );
}
//Various "cleanup" functions
-
- /*
+
+ /**
* Run the "tidy" command on text if the $wgUseTidy
* global is true
*
@@ -747,7 +791,7 @@ class NewParserTest extends MediaWikiTestCase {
return $text;
}
-
+
/**
* Remove last character if it is a newline
*/
@@ -760,12 +804,8 @@ class NewParserTest extends MediaWikiTestCase {
}
}
- public function showRunFile( $file ) {
- /* NOP */
- }
-
//Test options parser functions
-
+
protected function parseOptions( $instring ) {
$opts = array();
// foo
@@ -820,7 +860,7 @@ class NewParserTest extends MediaWikiTestCase {
}
return $opts;
}
-
+
protected function cleanupOption( $opt ) {
if ( substr( $opt, 0, 1 ) == '"' ) {
return substr( $opt, 1, -1 );
@@ -831,7 +871,7 @@ class NewParserTest extends MediaWikiTestCase {
}
return $opt;
}
-
+
/**
* Use a regex to find out the value of an option
* @param $key String: name of option val to retrieve
diff --git a/tests/phpunit/includes/parser/ParserHelpers.php b/tests/phpunit/includes/parser/ParserHelpers.php
deleted file mode 100644
index 4a6ce7c4..00000000
--- a/tests/phpunit/includes/parser/ParserHelpers.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-class PHPUnitParserTest extends ParserTest {
- function showTesting( $desc ) {
- /* Do nothing since we don't want to show info during PHPUnit testing. */
- }
-
- public function showSuccess( $desc ) {
- PHPUnit_Framework_Assert::assertTrue( true, $desc );
- return true;
- }
-
- public function showFailure( $desc, $expected, $got ) {
- PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc );
- return false;
- }
-
- public function setupRecorder( $options ) {
- $this->recorder = new PHPUnitTestRecorder( $this );
- }
-}
-
-class ParserUnitTest extends MediaWikiTestCase {
- private $test = "";
-
- public function __construct( $suite, $test = null ) {
- parent::__construct();
- $this->test = $test;
- $this->suite = $suite;
- }
-
- function count() { return 1; }
-
- public function run( PHPUnit_Framework_TestResult $result = null ) {
- PHPUnit_Framework_Assert::resetCount();
- if ( $result === NULL ) {
- $result = new PHPUnit_Framework_TestResult;
- }
-
- $this->suite->publishTestArticles(); // Add articles needed by the tests.
- $backend = new ParserTestSuiteBackend;
- $result->startTest( $this );
-
- // Support the transition to PHPUnit 3.5 where PHPUnit_Util_Timer is replaced with PHP_Timer
- if ( class_exists( 'PHP_Timer' ) ) {
- PHP_Timer::start();
- } else {
- PHPUnit_Util_Timer::start();
- }
-
- $r = false;
- try {
- # Run the test.
- # On failure, the subclassed backend will throw an exception with
- # the details.
- $pt = new PHPUnitParserTest;
- $r = $pt->runTest( $this->test['test'], $this->test['input'],
- $this->test['result'], $this->test['options'], $this->test['config']
- );
- }
- catch ( PHPUnit_Framework_AssertionFailedError $e ) {
-
- // PHPUnit_Util_Timer -> PHP_Timer support (see above)
- if ( class_exists( 'PHP_Timer' ) ) {
- $result->addFailure( $this, $e, PHP_Timer::stop() );
- } else {
- $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() );
- }
- }
- catch ( Exception $e ) {
- // PHPUnit_Util_Timer -> PHP_Timer support (see above)
- if ( class_exists( 'PHP_Timer' ) ) {
- $result->addFailure( $this, $e, PHP_Timer::stop() );
- } else {
- $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() );
- }
- }
-
- // PHPUnit_Util_Timer -> PHP_Timer support (see above)
- if ( class_exists( 'PHP_Timer' ) ) {
- $result->endTest( $this, PHP_Timer::stop() );
- } else {
- $result->endTest( $this, PHPUnit_Util_Timer::stop() );
- }
-
- $backend->recorder->record( $this->test['test'], $r );
- $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() );
-
- return $result;
- }
-
- public function toString() {
- return $this->test['test'];
- }
-
-}
-
-class ParserTestSuiteBackend extends PHPUnit_FrameWork_TestSuite {
- public $recorder;
- public $term;
- static $usePHPUnit = false;
-
- function __construct() {
- parent::__construct();
- $this->setupRecorder(null);
- self::$usePHPUnit = method_exists('PHPUnit_Framework_Assert', 'assertEquals');
- }
-
- function showTesting( $desc ) {
- }
-
- function showRunFile( $path ) {
- }
-
- function showTestResult( $desc, $result, $out ) {
- if ( $result === $out ) {
- return self::showSuccess( $desc, $result, $out );
- } else {
- return self::showFailure( $desc, $result, $out );
- }
- }
-
- public function setupRecorder( $options ) {
- $this->recorder = new PHPUnitTestRecorder( $this );
- }
-}
-
-class PHPUnitTestRecorder extends TestRecorder {
- function record( $test, $result ) {
- $this->total++;
- $this->success += $result;
-
- }
-
- function reportPercentage( $success, $total ) { }
-}
diff --git a/tests/phpunit/includes/parser/ParserPreloadTest.php b/tests/phpunit/includes/parser/ParserPreloadTest.php
new file mode 100644
index 00000000..0e8ef530
--- /dev/null
+++ b/tests/phpunit/includes/parser/ParserPreloadTest.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Basic tests for Parser::getPreloadText
+ * @author Antoine Musso
+ */
+class ParserPreloadTest extends MediaWikiTestCase {
+ private $testParser;
+ private $testParserOptions;
+ private $title;
+
+ function setUp() {
+ $this->testParserOptions = new ParserOptions();
+
+ $this->testParser = new Parser();
+ $this->testParser->Options( $this->testParserOptions );
+ $this->testParser->clearState();
+
+ $this->title = Title::newFromText( 'Preload Test' );
+ }
+
+ function tearDown() {
+ unset( $this->testParser );
+ unset( $this->title );
+ }
+
+ /**
+ * @covers Parser::getPreloadText
+ */
+ function testPreloadSimpleText() {
+ $this->assertPreloaded( 'simple', 'simple' );
+ }
+
+ /**
+ * @covers Parser::getPreloadText
+ */
+ function testPreloadedPreIsUnstripped() {
+ $this->assertPreloaded(
+ '<pre>monospaced</pre>',
+ '<pre>monospaced</pre>',
+ '<pre> in preloaded text must be unstripped (bug 27467)'
+ );
+ }
+
+ /**
+ * @covers Parser::getPreloadText
+ */
+ function testPreloadedNowikiIsUnstripped() {
+ $this->assertPreloaded(
+ '<nowiki>[[Dummy title]]</nowiki>',
+ '<nowiki>[[Dummy title]]</nowiki>',
+ '<nowiki> in preloaded text must be unstripped (bug 27467)'
+ );
+ }
+
+ function assertPreloaded( $expected, $text, $msg='') {
+ $this->assertEquals(
+ $expected,
+ $this->testParser->getPreloadText(
+ $text,
+ $this->title,
+ $this->testParserOptions
+ ),
+ $msg
+ );
+ }
+
+}
diff --git a/tests/phpunit/includes/parser/PreprocessorTest.php b/tests/phpunit/includes/parser/PreprocessorTest.php
index 7a5948d4..9d3499a0 100644
--- a/tests/phpunit/includes/parser/PreprocessorTest.php
+++ b/tests/phpunit/includes/parser/PreprocessorTest.php
@@ -49,43 +49,45 @@ class PreprocessorTest extends MediaWikiTestCase {
array( "== Foo ==\n== Bar == \n", "<root><h level=\"2\" i=\"1\">== Foo ==</h>\n<h level=\"2\" i=\"2\">== Bar == </h>\n</root>" ),
array( "===========", "<root><h level=\"5\" i=\"1\">===========</h></root>" ),
array( "Foo\n=\n==\n=\n", "<root>Foo\n=\n==\n=\n</root>" ),
- array( "{{Foo}}", "<root><template lineStart=\"1\"><title>Foo</title></template></root>" ),
+ array( "{{Foo}}", "<root><template><title>Foo</title></template></root>" ),
array( "\n{{Foo}}", "<root>\n<template lineStart=\"1\"><title>Foo</title></template></root>" ),
- array( "{{Foo|bar}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),
- array( "{{Foo|bar}}a", "<root><template lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),
- array( "{{Foo|bar|baz}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),
- array( "{{Foo|1=bar}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ),
- array( "{{Foo|=bar}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ),
- array( "{{Foo|bar=baz}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ),
- array( "{{Foo|1=bar|baz}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ),
- array( "{{Foo|1=bar|2=baz}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ),
- array( "{{Foo|bar|foo=baz}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ),
- array( "{{{1}}}", "<root><tplarg lineStart=\"1\"><title>1</title></tplarg></root>" ),
- array( "{{{1|}}}", "<root><tplarg lineStart=\"1\"><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
- array( "{{{Foo}}}", "<root><tplarg lineStart=\"1\"><title>Foo</title></tplarg></root>" ),
- array( "{{{Foo|}}}", "<root><tplarg lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
- array( "{{{Foo|bar|baz}}}", "<root><tplarg lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></tplarg></root>" ),
+ array( "{{Foo|bar}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template></root>" ),
+ array( "{{Foo|bar}}a", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part></template>a</root>" ),
+ array( "{{Foo|bar|baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></template></root>" ),
+ array( "{{Foo|1=bar}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part></template></root>" ),
+ array( "{{Foo|=bar}}", "<root><template><title>Foo</title><part><name></name>=<value>bar</value></part></template></root>" ),
+ array( "{{Foo|bar=baz}}", "<root><template><title>Foo</title><part><name>bar</name>=<value>baz</value></part></template></root>" ),
+ array( "{{Foo|{{bar}}=baz}}", "<root><template><title>Foo</title><part><name><template><title>bar</title></template></name>=<value>baz</value></part></template></root>" ),
+ array( "{{Foo|1=bar|baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name index=\"1\" /><value>baz</value></part></template></root>" ),
+ array( "{{Foo|1=bar|2=baz}}", "<root><template><title>Foo</title><part><name>1</name>=<value>bar</value></part><part><name>2</name>=<value>baz</value></part></template></root>" ),
+ array( "{{Foo|bar|foo=baz}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name>foo</name>=<value>baz</value></part></template></root>" ),
+ array( "{{{1}}}", "<root><tplarg><title>1</title></tplarg></root>" ),
+ array( "{{{1|}}}", "<root><tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
+ array( "{{{Foo}}}", "<root><tplarg><title>Foo</title></tplarg></root>" ),
+ array( "{{{Foo|}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value></value></part></tplarg></root>" ),
+ array( "{{{Foo|bar|baz}}}", "<root><tplarg><title>Foo</title><part><name index=\"1\" /><value>bar</value></part><part><name index=\"2\" /><value>baz</value></part></tplarg></root>" ),
array( "{<!-- -->{Foo}}", "<root>{<comment>&lt;!-- --&gt;</comment>{Foo}}</root>" ),
array( "{{{{Foobar}}}}", "<root>{<tplarg><title>Foobar</title></tplarg>}</root>" ),
- array( "{{{ {{Foo}} }}}", "<root><tplarg lineStart=\"1\"><title> <template><title>Foo</title></template> </title></tplarg></root>" ),
- array( "{{ {{{Foo}}} }}", "<root><template lineStart=\"1\"><title> <tplarg><title>Foo</title></tplarg> </title></template></root>" ),
- array( "{{{{{Foo}}}}}", "<root><template lineStart=\"1\"><title><tplarg><title>Foo</title></tplarg></title></template></root>" ),
- array( "{{{{{Foo}} }}}", "<root><tplarg lineStart=\"1\"><title><template><title>Foo</title></template> </title></tplarg></root>" ),
- array( "{{{{{{Foo}}}}}}", "<root><tplarg lineStart=\"1\"><title><tplarg><title>Foo</title></tplarg></title></tplarg></root>" ),
+ array( "{{{ {{Foo}} }}}", "<root><tplarg><title> <template><title>Foo</title></template> </title></tplarg></root>" ),
+ array( "{{ {{{Foo}}} }}", "<root><template><title> <tplarg><title>Foo</title></tplarg> </title></template></root>" ),
+ array( "{{{{{Foo}}}}}", "<root><template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ),
+ array( "{{{{{Foo}} }}}", "<root><tplarg><title><template><title>Foo</title></template> </title></tplarg></root>" ),
+ array( "{{{{{{Foo}}}}}}", "<root><tplarg><title><tplarg><title>Foo</title></tplarg></title></tplarg></root>" ),
array( "{{{{{{Foo}}}}}", "<root>{<template><title><tplarg><title>Foo</title></tplarg></title></template></root>" ),
array( "[[[Foo]]", "<root>[[[Foo]]</root>" ),
- array( "{{Foo|[[[[bar]]|baz]]}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name index=\"1\" /><value>[[[[bar]]|baz]]</value></part></template></root>" ), // This test is important, since it means the difference between having the [[ rule stacked or not
+ array( "{{Foo|[[[[bar]]|baz]]}}", "<root><template><title>Foo</title><part><name index=\"1\" /><value>[[[[bar]]|baz]]</value></part></template></root>" ), // This test is important, since it means the difference between having the [[ rule stacked or not
array( "{{Foo|[[[[bar]|baz]]}}", "<root>{{Foo|[[[[bar]|baz]]}}</root>" ),
array( "{{Foo|Foo [[[[bar]|baz]]}}", "<root>{{Foo|Foo [[[[bar]|baz]]}}</root>" ),
array( "Foo <display map>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr></attr><inner>Bar</inner><close>&lt;/display map &gt;</close></ext>Baz</root>" ),
array( "Foo <display map foo>Bar</display map >Baz", "<root>Foo <ext><name>display map</name><attr> foo</attr><inner>Bar</inner><close>&lt;/display map &gt;</close></ext>Baz</root>" ),
array( "Foo <gallery bar=\"baz\" />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;baz&quot; </attr></ext></root>" ),
+ array( "Foo <gallery bar=\"1\" baz=2 />", "<root>Foo <ext><name>gallery</name><attr> bar=&quot;1&quot; baz=2 </attr></ext></root>" ),
array( "</foo>Foo<//foo>", "<root><ext><name>/foo</name><attr></attr><inner>Foo</inner><close>&lt;//foo&gt;</close></ext></root>" ), # Worth blacklisting IMHO
- array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template lineStart=\"1\"><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
- array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template lineStart=\"1\"><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>"),
- array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template lineStart=\"1\"><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>"),
- array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template lineStart=\"1\"><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
- array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template lineStart=\"1\"><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>"),
+ array( "{{#ifexpr: ({{{1|1}}} = 2) | Foo | Bar }}", "<root><template><title>#ifexpr: (<tplarg><title>1</title><part><name index=\"1\" /><value>1</value></part></tplarg> = 2) </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
+ array( "{{#if: {{{1|}}} | Foo | {{Bar}} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> <template><title>Bar</title></template> </value></part></template></root>"),
+ array( "{{#if: {{{1|}}} | Foo | [[Bar]] }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> Foo </value></part><part><name index=\"2\" /><value> [[Bar]] </value></part></template></root>"),
+ array( "{{#if: {{{1|}}} | [[Foo]] | Bar }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> [[Foo]] </value></part><part><name index=\"2\" /><value> Bar </value></part></template></root>"),
+ array( "{{#if: {{{1|}}} | 1 | {{#if: {{{1|}}} | 2 | 3 }} }}", "<root><template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 1 </value></part><part><name index=\"2\" /><value> <template><title>#if: <tplarg><title>1</title><part><name index=\"1\" /><value></value></part></tplarg> </title><part><name index=\"1\" /><value> 2 </value></part><part><name index=\"2\" /><value> 3 </value></part></template> </value></part></template></root>"),
array( "{{ {{Foo}}", "<root>{{ <template><title>Foo</title></template></root>"),
array( "{{Foobar {{Foo}} {{Bar}} {{Baz}} ", "<root>{{Foobar <template><title>Foo</title></template> <template><title>Bar</title></template> <template><title>Baz</title></template> </root>"),
array( "[[Foo]] |", "<root>[[Foo]] |</root>"),
@@ -97,19 +99,54 @@ class PreprocessorTest extends MediaWikiTestCase {
array( "{{Foo|bar=[[baz]}}", "<root>{{Foo|bar=[[baz]}}</root>"),
array( "{{foo|", "<root>{{foo|</root>"),
array( "{{foo|}", "<root>{{foo|}</root>"),
- array( "{{foo|} }}", "<root><template lineStart=\"1\"><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>"),
+ array( "{{foo|} }}", "<root><template><title>foo</title><part><name index=\"1\" /><value>} </value></part></template></root>"),
array( "{{foo|bar=|}", "<root>{{foo|bar=|}</root>"),
array( "{{Foo|} Bar=", "<root>{{Foo|} Bar=</root>"),
- array( "{{Foo|} Bar=}}", "<root><template lineStart=\"1\"><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>"),
+ array( "{{Foo|} Bar=}}", "<root><template><title>Foo</title><part><name>} Bar</name>=<value></value></part></template></root>"),
/* array( file_get_contents( dirname( __FILE__ ) . '/QuoteQuran.txt' ), file_get_contents( dirname( __FILE__ ) . '/QuoteQuranExpanded.txt' ) ), */
);
}
/**
+ * Get XML preprocessor tree from the preprocessor (which may not be the
+ * native XML-based one).
+ *
+ * @param string $wikiText
+ * @return string
+ */
+ function preprocessToXml( $wikiText ) {
+ if ( method_exists( $this->mPreprocessor, 'preprocessToXml' ) ) {
+ return $this->normalizeXml( $this->mPreprocessor->preprocessToXml( $wikiText ) );
+ }
+
+ $dom = $this->mPreprocessor->preprocessToObj( $wikiText );
+ if ( is_callable( array( $dom, 'saveXML' ) ) ) {
+ return $dom->saveXML();
+ } else {
+ return $this->normalizeXml( $dom->__toString() );
+ }
+ }
+
+ /**
+ * Normalize XML string to the form that a DOMDocument saves out.
+ *
+ * @param string $xml
+ * @return string
+ */
+ function normalizeXml( $xml ) {
+ return preg_replace( '!<([a-z]+)/>!', '<$1></$1>', str_replace( ' />', '/>', $xml ) );
+
+ $dom = new DOMDocument();
+ // 1 << 19 == XML_PARSE_HUGE, needed so newer versions of libxml2 don't barf when the XML is >256 levels deep
+ $dom->loadXML( $xml, 1 << 19 );
+ return $dom->saveXML();
+ }
+
+ /**
* @dataProvider provideCases
*/
function testPreprocessorOutput( $wikiText, $expectedXml ) {
- $this->assertEquals( $expectedXml, $this->mPreprocessor->preprocessToXml( $wikiText ) );
+ $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
}
/**
@@ -130,11 +167,12 @@ class PreprocessorTest extends MediaWikiTestCase {
function testPreprocessorOutputFiles( $filename ) {
$folder = dirname( __FILE__ ) . "/../../../parser/preprocess";
$wikiText = file_get_contents( "$folder/$filename.txt" );
- $output = $this->mPreprocessor->preprocessToXml( $wikiText );
+ $output = $this->preprocessToXml( $wikiText );
$expectedFilename = "$folder/$filename.expected";
if ( file_exists( $expectedFilename ) ) {
- $this->assertStringEqualsFile( $expectedFilename, $output );
+ $expectedXml = $this->normalizeXml( file_get_contents( $expectedFilename ) );
+ $this->assertEquals( $expectedXml, $output );
} else {
$tempFilename = tempnam( $folder, "$filename." );
file_put_contents( $tempFilename, $output );
@@ -189,7 +227,7 @@ class PreprocessorTest extends MediaWikiTestCase {
* @dataProvider provideHeadings
*/
function testHeadings( $wikiText, $expectedXml ) {
- $this->assertEquals( $expectedXml, $this->mPreprocessor->preprocessToXml( $wikiText ) );
+ $this->assertEquals( $this->normalizeXml( $expectedXml ), $this->preprocessToXml( $wikiText ) );
}
}
diff --git a/tests/phpunit/includes/parser/TagHooks.php b/tests/phpunit/includes/parser/TagHooksTest.php
index 713ce846..713ce846 100644
--- a/tests/phpunit/includes/parser/TagHooks.php
+++ b/tests/phpunit/includes/parser/TagHooksTest.php