Merge "Remove ResourceLoaderGetStartupModules hook"
[lhc/web/wiklou.git] / tests / testHelpers.inc
index 88e5885..8c24f39 100644 (file)
@@ -318,7 +318,7 @@ class DbTestRecorder extends DbTestPreviewer {
                        array(
                                'tr_date' => $this->db->timestamp(),
                                'tr_mw_version' => $this->version,
-                               'tr_php_version' => phpversion(),
+                               'tr_php_version' => PHP_VERSION,
                                'tr_db_version' => $this->db->getServerVersion(),
                                'tr_uname' => php_uname()
                        ),
@@ -333,8 +333,8 @@ class DbTestRecorder extends DbTestPreviewer {
        /**
         * Record an individual test item's success or failure to the db
         *
-        * @param $test String
-        * @param $result Boolean
+        * @param string $test
+        * @param bool $result
         */
        function record( $test, $result ) {
                parent::record( $test, $result );
@@ -419,7 +419,7 @@ class TestFileIterator implements Iterator {
                        $this->lineNum++;
                        $matches = array();
 
-                       if ( preg_match( '/^!!\s*(\w+)/', $line, $matches ) ) {
+                       if ( preg_match( '/^!!\s*(\S+)/', $line, $matches ) ) {
                                $this->section = strtolower( $matches[1] );
 
                                if ( $this->section == 'endarticle' ) {
@@ -465,10 +465,28 @@ class TestFileIterator implements Iterator {
                                        continue;
                                }
 
+                               if ( $this->section == 'endtransparenthooks' ) {
+                                       $this->checkSection( 'transparenthooks' );
+
+                                       foreach ( explode( "\n", $this->sectionData['transparenthooks'] ) as $line ) {
+                                               $line = trim( $line );
+
+                                               if ( $line ) {
+                                                       $delayedParserTest->requireTransparentHook( $line );
+                                               }
+                                       }
+
+                                       $this->clearSection();
+
+                                       continue;
+                               }
+
                                if ( $this->section == 'end' ) {
                                        $this->checkSection( 'test' );
-                                       $this->checkSection( 'input' );
-                                       $this->checkSection( 'result' );
+                                       // "input" and "result" are old section names allowed
+                                       // for backwards-compatibility.
+                                       $input = $this->checkSection( array( 'wikitext', 'input' ), false );
+                                       $result = $this->checkSection( array( 'html/php', 'html/*', 'html', 'result' ), false );
 
                                        if ( !isset( $this->sectionData['options'] ) ) {
                                                $this->sectionData['options'] = '';
@@ -478,8 +496,9 @@ class TestFileIterator implements Iterator {
                                                $this->sectionData['config'] = '';
                                        }
 
-                                       if ( ( ( preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runDisabled )
-                                               || ( preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runParsoid )
+                                       if ( $input == false || $result == false ||
+                                               ( ( preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runDisabled )
+                                               || ( preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) && $result != 'html/php' && !$this->parserTest->runParsoid )
                                                || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )
                                        ) {
                                                # disabled test
@@ -501,8 +520,8 @@ class TestFileIterator implements Iterator {
 
                                        $this->test = array(
                                                'test' => ParserTest::chomp( $this->sectionData['test'] ),
-                                               'input' => ParserTest::chomp( $this->sectionData['input'] ),
-                                               'result' => ParserTest::chomp( $this->sectionData['result'] ),
+                                               'input' => ParserTest::chomp( $this->sectionData[ $input ] ),
+                                               'result' => ParserTest::chomp( $this->sectionData[ $result ] ),
                                                'options' => ParserTest::chomp( $this->sectionData['options'] ),
                                                'config' => ParserTest::chomp( $this->sectionData['config'] ),
                                        );
@@ -527,7 +546,6 @@ class TestFileIterator implements Iterator {
                return false;
        }
 
-
        /**
         * Clear section name and its data
         */
@@ -539,27 +557,55 @@ class TestFileIterator implements Iterator {
 
        /**
         * Verify the current section data has some value for the given token
-        * name (first parameter).
+        * name(s) (first parameter).
         * Throw an exception if it is not set, referencing current section
         * and adding the current file name and line number
         *
-        * @param $token String: expected token that should have been mentionned before closing this section
+        * @param string|array $token Expected token(s) that should have been
+        * mentioned before closing this section
+        * @param bool $fatal True iff an exception should be thrown if
+        * the section is not found.
         */
-       private function checkSection( $token ) {
+       private function checkSection( $tokens, $fatal = true ) {
                if ( is_null( $this->section ) ) {
                        throw new MWException( __METHOD__ . " can not verify a null section!\n" );
                }
+               if ( !is_array( $tokens ) ) {
+                       $tokens = array( $tokens );
+               }
+               if ( count( $tokens ) == 0 ) {
+                       throw new MWException( __METHOD__ . " can not verify zero sections!\n" );
+               }
+
+               $data = $this->sectionData;
+               $tokens = array_filter( $tokens, function ( $token ) use ( $data ) {
+                       return isset( $data[ $token ] );
+               } );
 
-               if ( !isset( $this->sectionData[$token] ) ) {
+               if ( count( $tokens ) == 0 ) {
+                       if ( !$fatal ) {
+                               return false;
+                       }
                        throw new MWException( sprintf(
                                "'%s' without '%s' at line %s of %s\n",
                                $this->section,
-                               $token,
+                               implode( ',', $tokens ),
                                $this->lineNum,
                                $this->file
                        ) );
                }
-               return true;
+               if ( count( $tokens ) > 1 ) {
+                       throw new MWException( sprintf(
+                               "'%s' with unexpected tokens '%s' at line %s of %s\n",
+                               $this->section,
+                               implode( ',', $tokens ),
+                               $this->lineNum,
+                               $this->file
+                       ) );
+               }
+
+               $tokens = array_values( $tokens );
+               return $tokens[ 0 ];
        }
 }
 
@@ -571,6 +617,7 @@ class DelayedParserTest {
        /** Initialized on construction */
        private $hooks;
        private $fnHooks;
+       private $transparentHooks;
 
        public function __construct() {
                $this->reset();
@@ -583,11 +630,13 @@ class DelayedParserTest {
        public function reset() {
                $this->hooks = array();
                $this->fnHooks = array();
+               $this->transparentHooks = array();
        }
 
        /**
         * Called whenever we actually want to run the hook.
         * Should be the case if we found the parserTest is not disabled
+        * @param ParserTest|NewParserTest $parserTest
         */
        public function unleash( &$parserTest ) {
                if ( !( $parserTest instanceof ParserTest || $parserTest instanceof NewParserTest )     ) {
@@ -610,6 +659,14 @@ class DelayedParserTest {
                        }
                }
 
+               # Trigger delayed transparent hooks. Any failure will make us abort
+               foreach ( $this->transparentHooks as $hook ) {
+                       $ret = $parserTest->requireTransparentHook( $hook );
+                       if ( !$ret ) {
+                               return false;
+                       }
+               }
+
                # Delayed execution was successful.
                return true;
        }
@@ -617,6 +674,7 @@ class DelayedParserTest {
        /**
         * Similar to ParserTest object but does not run anything
         * Use unleash() to really execute the hook
+        * @param string $hook
         */
        public function requireHook( $hook ) {
                $this->hooks[] = $hook;
@@ -625,9 +683,55 @@ class DelayedParserTest {
        /**
         * Similar to ParserTest object but does not run anything
         * Use unleash() to really execute the hook function
+        * @param string $fnHook
         */
        public function requireFunctionHook( $fnHook ) {
                $this->fnHooks[] = $fnHook;
        }
 
+       /**
+        * Similar to ParserTest object but does not run anything
+        * Use unleash() to really execute the hook function
+        * @param string $fnHook
+        */
+       public function requireTransparentHook( $hook ) {
+               $this->transparentHooks[] = $hook;
+       }
+
+}
+
+/**
+ * Initialize and detect the DjVu files support
+ */
+class DjVuSupport {
+
+       /**
+        * Initialises DjVu tools global with default values
+        */
+       public function __construct() {
+               global $wgDjvuRenderer, $wgDjvuDump, $wgDjvuToXML, $wgFileExtensions, $wgDjvuTxt;
+
+               $wgDjvuRenderer = $wgDjvuRenderer ? $wgDjvuRenderer : '/usr/bin/ddjvu';
+               $wgDjvuDump = $wgDjvuDump ? $wgDjvuDump : '/usr/bin/djvudump';
+               $wgDjvuToXML = $wgDjvuToXML ? $wgDjvuToXML : '/usr/bin/djvutoxml';
+               $wgDjvuTxt = $wgDjvuTxt ? $wgDjvuTxt : '/usr/bin/djvutxt';
+
+               if ( !in_array( 'djvu', $wgFileExtensions ) ) {
+                       $wgFileExtensions[] = 'djvu';
+               }
+       }
+
+       /**
+        * Returns if the DjVu tools are usable
+        *
+        * @return bool
+        */
+       public function isEnabled() {
+               global $wgDjvuRenderer, $wgDjvuDump, $wgDjvuToXML, $wgDjvuTxt;
+
+               return is_executable( $wgDjvuRenderer )
+                       && is_executable( $wgDjvuDump )
+                       && is_executable( $wgDjvuToXML )
+                       && is_executable( $wgDjvuTxt );
+       }
 }