Add tests for the just-fixed bug 553, and broken cases regarding
[lhc/web/wiklou.git] / maintenance / parserTests.php
index 6394bae..cc1d49c 100644 (file)
@@ -30,8 +30,20 @@ $optionsWithArgs = array('regex');
 require_once( 'commandLine.inc' );
 require_once( 'languages/LanguageUtf8.php' );
 
+/** */
 class ParserTest {
-       
+       /**
+        * boolean $color whereas output should be colorized
+        * @access private
+        */
+       var $color;
+
+       /**
+        * boolean $lightcolor whereas output should use light colors
+        * @access private
+        */
+       var $lightcolor;
+
        /**
         * Sets terminal colorization and diff/quick modes depending on OS and
         * command-line options (--color and --quick).
@@ -40,10 +52,14 @@ class ParserTest {
         */
        function ParserTest() {
                global $options;
+               $this->lightcolor = false;
                if( isset( $_SERVER['argv'] ) && in_array( '--color', $_SERVER['argv'] ) ) {
                        $this->color = true;
                } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=yes', $_SERVER['argv'] ) ) {
                        $this->color = true;
+               } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=light', $_SERVER['argv'] ) ) {
+                       $this->color = true;
+                       $this->lightcolor = true;
                } elseif( isset( $_SERVER['argv'] ) && in_array( '--color=no', $_SERVER['argv'] ) ) {
                        $this->color = false;
                } elseif( wfIsWindows() ) {
@@ -115,7 +131,7 @@ class ParserTest {
                                        if( !isset( $data['article'] ) ) {
                                                die( "'endarticle' without 'article' at line $n\n" );
                                        }
-                                       $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']));
+                                       $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']), $n);
                                        $data = array();
                                        $section = null;
                                        continue;
@@ -155,6 +171,9 @@ class ParserTest {
                                        $section = null;
                                        continue;
                                }
+                               if ( isset ($data[$section] ) ) {
+                                       die ( "duplicate section '$section' at line $n\n" );
+                               }
                                $data[$section] = '';
                                continue;
                        }
@@ -232,6 +251,7 @@ class ParserTest {
                        }
 
                        if ($GLOBALS['wgUseTidy']) {
+                               $out = Parser::tidy($out);
                                $result = Parser::tidy($result);
                        }
                }
@@ -252,6 +272,13 @@ class ParserTest {
         * @access private
         */
        function setupGlobals($opts = '') {
+               # Save the prefixed / quoted table names for later use when we make the temporaries.
+               $db =& wfGetDB( DB_READ );
+               $this->oldTableNames = array();
+               foreach( $this->listTables() as $table ) {
+                       $this->oldTableNames[$table] = $db->tableName( $table );
+               }
+               
                $settings = array(
                        'wgServer' => 'http://localhost',
                        'wgScript' => '/index.php',
@@ -265,7 +292,7 @@ class ParserTest {
                        
                        'wgLoadBalancer' => LoadBalancer::newFromParams( $GLOBALS['wgDBservers'] ),
                        'wgLang' => new LanguageUtf8(),
-                       'wgNamespacesWithSubpages' => array( 0 => preg_match('/subpage/i', $opts)),
+                       'wgNamespacesWithSubpages' => array( 0 => preg_match('/\\bsubpage\\b/i', $opts)),
                        );
                $this->savedGlobals = array();
                foreach( $settings as $var => $val ) {
@@ -276,33 +303,84 @@ class ParserTest {
                $this->setupDatabase();
        }
        
+       # List of temporary tables to create, without prefix
+       # Some of these probably aren't necessary
+       function listTables() {
+               return array('user', 'cur', 'old', 'links',
+                       'brokenlinks', 'imagelinks', 'categorylinks',
+                       'linkscc', 'site_stats', 'hitcounter',
+                       'ipblocks', 'image', 'oldimage',
+                       'recentchanges',
+                       'watchlist', 'math', 'searchindex',
+                       'interwiki', 'querycache',
+                       'objectcache'
+               );
+       }
+       
        /**
         * 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.
         *
-        * This is ugly, but we need a way to modify the database
-        * without breaking anything. Currently it isn't possible
-        * to roll back transactions, which might help with this.
-        * -- wtm
-        *
         * @access private
         */
        function setupDatabase() {
                static $setupDB = false;
-               if (!$setupDB && $GLOBALS['wgDBprefix'] === 'parsertest') {
+               global $wgDBprefix;
+
+               # Make sure we don't mess with the live DB
+               if (!$setupDB && $wgDBprefix === 'parsertest') {
                        $db =& wfGetDB( DB_MASTER );
-                       if (0) {
-                               # XXX CREATE TABLE ... LIKE requires MySQL 4.1
-                               $tables = array('cur', 'interwiki', 'brokenlinks', 'recentchanges');
+
+                       $tables = $this->listTables();
+
+                       if (!(strcmp($db->getServerVersion(), '4.1') < 0 and stristr($db->getSoftwareLink(), 'MySQL'))) {
+                               # Database that supports CREATE TABLE ... LIKE
                                foreach ($tables as $tbl) {
-                                       $db->query('CREATE TEMPORARY TABLE ' . $GLOBALS['wgDBprefix'] . "$tbl LIKE $tbl");
+                                       $newTableName = $db->tableName( $tbl );
+                                       $tableName = $this->oldTableNames[$tbl];
+                                       $db->query("CREATE TEMPORARY TABLE $newTableName (LIKE $tableName INCLUDING DEFAULTS)");
                                }
+                       } else {
+                               # Hack for MySQL versions < 4.1, which don't support
+                               # "CREATE TABLE ... LIKE". Note that
+                               # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0"
+                               # would not create the indexes we need....
+                               foreach ($tables as $tbl) {
+                                       $res = $db->query("SHOW CREATE TABLE $tbl");
+                                       $row = $db->fetchRow($res);
+                                       $create = $row[1];
+                                       $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `'
+                                               . $wgDBprefix . '\\1`', $create);
+                                       if ($create === $create_tmp) {
+                                               # Couldn't do replacement
+                                               die("could not create temporary table $tbl");
+                                       }
+                                       $db->query($create_tmp);
+                               }
+
                        }
-                       else {
-                               # HACK, sorry
-                               dbsource( 'maintenance/parserTests.sql', $db );
-                       }
+
+                       # Hack: insert a few Wikipedia in-project interwiki prefixes,
+                       # for testing inter-language links
+                       $db->insertArray( 'interwiki', array(
+                               array( 'iw_prefix' => 'Wikipedia',
+                                      'iw_url'    => 'http://en.wikipedia.org/wiki/$1',
+                                      'iw_local'  => 0 ),
+                               array( 'iw_prefix' => 'MeatBall',
+                                      'iw_url'    => 'http://www.usemod.com/cgi-bin/mb.pl?$1',
+                                      'iw_local'  => 0 ),
+                               array( 'iw_prefix' => 'zh',
+                                      'iw_url'    => 'http://zh.wikipedia.org/wiki/$1',
+                                      'iw_local'  => 1 ),
+                               array( 'iw_prefix' => 'es',
+                                      'iw_url'    => 'http://es.wikipedia.org/wiki/$1',
+                                      'iw_local'  => 1 ),
+                               array( 'iw_prefix' => 'fr',
+                                      'iw_url'    => 'http://fr.wikipedia.org/wiki/$1',
+                                      'iw_local'  => 1 ) ) );
+
+
                        $setupDB = true;
                }
        }
@@ -396,7 +474,11 @@ class ParserTest {
         * @access private
         */
        function termColor( $color ) {
-               return $this->color ? "\x1b[{$color}m" : '';
+               if($this->lightcolor) {
+                       return $this->color ? "\x1b[1;{$color}m" : '';
+               } else {
+                       return $this->color ? "\x1b[{$color}m" : '';
+               }
        }
        
        /**
@@ -430,14 +512,22 @@ class ParserTest {
         * Insert a temporary test article
         * @param $name string the title, including any prefix
         * @param $text string the article text
+        * @param $line int the input line number, for reporting errors
         * @static
         * @access private
         */
-       function addArticle($name, $text) {
-               # TODO: check if article exists and die gracefully
-               # if we are trying to insert a duplicate
+       function addArticle($name, $text, $line) {
                $this->setupGlobals();
                $title = Title::newFromText( $name );
+               if ( is_null($title) ) {
+                       die( "invalid title at line $line\n" );
+               }
+
+               $aid = $title->getArticleID( GAID_FOR_UPDATE );
+               if ($aid != 0) {
+                       die( "duplicate article at line $line\n" );
+               }
+
                $art = new Article($title);
                $art->insertNewArticle($text, '', false, false );
                $this->teardownGlobals();