Add @covers tags to parser tests
[lhc/web/wiklou.git] / tests / phpunit / includes / parser / ParserOptionsTest.php
index aacdb1a..93ab35c 100644 (file)
@@ -3,8 +3,79 @@
 use Wikimedia\TestingAccessWrapper;
 use Wikimedia\ScopedCallback;
 
+/**
+ * @covers ParserOptions
+ */
 class ParserOptionsTest extends MediaWikiTestCase {
 
+       private static function clearCache() {
+               $wrap = TestingAccessWrapper::newFromClass( ParserOptions::class );
+               $wrap->defaults = null;
+               $wrap->lazyOptions = [
+                       'dateformat' => [ ParserOptions::class, 'initDateFormat' ],
+               ];
+               $wrap->inCacheKey = [
+                       'dateformat' => true,
+                       'numberheadings' => true,
+                       'thumbsize' => true,
+                       'stubthreshold' => true,
+                       'printable' => true,
+                       'userlang' => true,
+                       'wrapclass' => true,
+               ];
+       }
+
+       protected function setUp() {
+               global $wgHooks;
+
+               parent::setUp();
+               self::clearCache();
+
+               $this->setMwGlobals( [
+                       'wgRenderHashAppend' => '',
+                       'wgHooks' => [
+                               'PageRenderingHash' => [],
+                       ] + $wgHooks,
+               ] );
+       }
+
+       protected function tearDown() {
+               self::clearCache();
+               parent::tearDown();
+       }
+
+       /**
+        * @dataProvider provideIsSafeToCache
+        * @param bool $expect Expected value
+        * @param array $options Options to set
+        */
+       public function testIsSafeToCache( $expect, $options ) {
+               $popt = ParserOptions::newCanonical();
+               foreach ( $options as $name => $value ) {
+                       $popt->setOption( $name, $value );
+               }
+               $this->assertSame( $expect, $popt->isSafeToCache() );
+       }
+
+       public static function provideIsSafeToCache() {
+               return [
+                       'No overrides' => [ true, [] ],
+                       'In-key options are ok' => [ true, [
+                               'thumbsize' => 1e100,
+                               'wrapclass' => false,
+                       ] ],
+                       'Non-in-key options are not ok' => [ false, [
+                               'removeComments' => false,
+                       ] ],
+                       'Canonical override, not default (1)' => [ true, [
+                               'tidy' => true,
+                       ] ],
+                       'Canonical override, not default (2)' => [ false, [
+                               'tidy' => false,
+                       ] ],
+               ];
+       }
+
        /**
         * @dataProvider provideOptionsHash
         * @param array $usedOptions Used options
@@ -16,7 +87,6 @@ class ParserOptionsTest extends MediaWikiTestCase {
                global $wgHooks;
 
                $globals += [
-                       'wgRenderHashAppend' => '',
                        'wgHooks' => [],
                ];
                $globals['wgHooks'] += [
@@ -24,30 +94,38 @@ class ParserOptionsTest extends MediaWikiTestCase {
                ] + $wgHooks;
                $this->setMwGlobals( $globals );
 
-               $popt = new ParserOptions();
-               foreach ( $options as $setter => $value ) {
-                       $popt->$setter( $value );
+               $popt = ParserOptions::newCanonical();
+               foreach ( $options as $name => $value ) {
+                       $popt->setOption( $name, $value );
                }
                $this->assertSame( $expect, $popt->optionsHash( $usedOptions ) );
        }
 
        public static function provideOptionsHash() {
-               $used = [ 'wrapclass', 'editsection', 'printable' ];
+               $used = [ 'wrapclass', 'printable' ];
+
+               $classWrapper = TestingAccessWrapper::newFromClass( ParserOptions::class );
+               $classWrapper->getDefaults();
+               $allUsableOptions = array_diff(
+                       array_keys( $classWrapper->inCacheKey ),
+                       array_keys( $classWrapper->lazyOptions )
+               );
 
                return [
-                       'Canonical options, nothing used' => [ [], '*!*!*!*!*!*', [] ],
-                       'Canonical options, used some options' => [ $used, '*!*!*!*!*', [] ],
+                       'Canonical options, nothing used' => [ [], 'canonical', [] ],
+                       'Canonical options, used some options' => [ $used, 'canonical', [] ],
                        'Used some options, non-default values' => [
                                $used,
-                               '*!*!*!*!*!printable=1!wrapclass=foobar',
+                               'printable=1!wrapclass=foobar',
                                [
-                                       'setWrapOutputClass' => 'foobar',
-                                       'setIsPrintable' => true,
+                                       'wrapclass' => 'foobar',
+                                       'printable' => true,
                                ]
                        ],
+                       'Canonical options, used all non-lazy options' => [ $allUsableOptions, 'canonical', [] ],
                        'Canonical options, nothing used, but with hooks and $wgRenderHashAppend' => [
                                [],
-                               '*!*!*!*!*!wgRenderHashAppend!*!onPageRenderingHash',
+                               'canonical!wgRenderHashAppend!onPageRenderingHash',
                                [],
                                [
                                        'wgRenderHashAppend' => '!wgRenderHashAppend',
@@ -61,9 +139,52 @@ class ParserOptionsTest extends MediaWikiTestCase {
                $confstr .= '!onPageRenderingHash';
        }
 
+       // Test weird historical behavior is still weird
+       public function testOptionsHashEditSection() {
+               $popt = ParserOptions::newCanonical();
+               $popt->registerWatcher( function ( $name ) {
+                       $this->assertNotEquals( 'editsection', $name );
+               } );
+
+               $this->assertTrue( $popt->getEditSection() );
+               $this->assertSame( 'canonical', $popt->optionsHash( [] ) );
+               $this->assertSame( 'canonical', $popt->optionsHash( [ 'editsection' ] ) );
+
+               $popt->setEditSection( false );
+               $this->assertFalse( $popt->getEditSection() );
+               $this->assertSame( 'canonical', $popt->optionsHash( [] ) );
+               $this->assertSame( 'editsection=0', $popt->optionsHash( [ 'editsection' ] ) );
+       }
+
+       /**
+        * @expectedException InvalidArgumentException
+        * @expectedExceptionMessage Unknown parser option bogus
+        */
+       public function testGetInvalidOption() {
+               $popt = ParserOptions::newCanonical();
+               $popt->getOption( 'bogus' );
+       }
+
+       /**
+        * @expectedException InvalidArgumentException
+        * @expectedExceptionMessage Unknown parser option bogus
+        */
+       public function testSetInvalidOption() {
+               $popt = ParserOptions::newCanonical();
+               $popt->setOption( 'bogus', true );
+       }
+
        public function testMatches() {
-               $popt1 = new ParserOptions();
-               $popt2 = new ParserOptions();
+               $classWrapper = TestingAccessWrapper::newFromClass( ParserOptions::class );
+               $oldDefaults = $classWrapper->defaults;
+               $oldLazy = $classWrapper->lazyOptions;
+               $reset = new ScopedCallback( function () use ( $classWrapper, $oldDefaults, $oldLazy ) {
+                       $classWrapper->defaults = $oldDefaults;
+                       $classWrapper->lazyOptions = $oldLazy;
+               } );
+
+               $popt1 = ParserOptions::newCanonical();
+               $popt2 = ParserOptions::newCanonical();
                $this->assertTrue( $popt1->matches( $popt2 ) );
 
                $popt1->enableLimitReport( true );
@@ -72,6 +193,46 @@ class ParserOptionsTest extends MediaWikiTestCase {
 
                $popt2->setTidy( !$popt2->getTidy() );
                $this->assertFalse( $popt1->matches( $popt2 ) );
+
+               $ctr = 0;
+               $classWrapper->defaults += [ __METHOD__ => null ];
+               $classWrapper->lazyOptions += [ __METHOD__ => function () use ( &$ctr ) {
+                       return ++$ctr;
+               } ];
+               $popt1 = ParserOptions::newCanonical();
+               $popt2 = ParserOptions::newCanonical();
+               $this->assertFalse( $popt1->matches( $popt2 ) );
+
+               ScopedCallback::consume( $reset );
+       }
+
+       public function testAllCacheVaryingOptions() {
+               global $wgHooks;
+
+               // $wgHooks is already saved in self::setUp(), so we can modify it freely here
+               $wgHooks['ParserOptionsRegister'] = [];
+               $this->assertSame( [
+                       'dateformat', 'numberheadings', 'printable', 'stubthreshold',
+                       'thumbsize', 'userlang', 'wrapclass',
+               ], ParserOptions::allCacheVaryingOptions() );
+
+               self::clearCache();
+
+               $wgHooks['ParserOptionsRegister'][] = function ( &$defaults, &$inCacheKey ) {
+                       $defaults += [
+                               'foo' => 'foo',
+                               'bar' => 'bar',
+                               'baz' => 'baz',
+                       ];
+                       $inCacheKey += [
+                               'foo' => true,
+                               'bar' => false,
+                       ];
+               };
+               $this->assertSame( [
+                       'dateformat', 'foo', 'numberheadings', 'printable', 'stubthreshold',
+                       'thumbsize', 'userlang', 'wrapclass',
+               ], ParserOptions::allCacheVaryingOptions() );
        }
 
 }