From: Amir Sarabadani Date: Sun, 7 Jul 2019 23:28:25 +0000 (+0200) Subject: Move unit tests, round III X-Git-Tag: 1.34.0-rc.0~1108^2 X-Git-Url: http://git.cyclocoop.org/data/File:Image2.gif?a=commitdiff_plain;h=57261a926cbfa729cb0f224773bd94e8e142e8a8;p=lhc%2Fweb%2Fwiklou.git Move unit tests, round III Depends-On: I16691fc8ac063705ba0c2bc63b96c4534ca8660b Bug: T87781 Change-Id: I5e1ab06e3decef6cc6090551d54dc4314ab9314a --- diff --git a/tests/phpunit/includes/DerivativeRequestTest.php b/tests/phpunit/includes/DerivativeRequestTest.php deleted file mode 100644 index f33022b352..0000000000 --- a/tests/phpunit/includes/DerivativeRequestTest.php +++ /dev/null @@ -1,21 +0,0 @@ -setIP( '1.2.3.4' ); - $derivative = new DerivativeRequest( $original, [] ); - - $this->assertEquals( '1.2.3.4', $derivative->getIP() ); - - $derivative->setIP( '5.6.7.8' ); - - $this->assertEquals( '5.6.7.8', $derivative->getIP() ); - $this->assertEquals( '1.2.3.4', $original->getIP() ); - } - -} diff --git a/tests/phpunit/includes/SanitizerValidateEmailTest.php b/tests/phpunit/includes/SanitizerValidateEmailTest.php deleted file mode 100644 index c4e430848b..0000000000 --- a/tests/phpunit/includes/SanitizerValidateEmailTest.php +++ /dev/null @@ -1,105 +0,0 @@ -assertEquals( - $expected, - Sanitizer::validateEmail( $addr ), - $msg - ); - } - - private function valid( $addr, $msg = '' ) { - $this->checkEmail( $addr, true, $msg ); - } - - private function invalid( $addr, $msg = '' ) { - $this->checkEmail( $addr, false, $msg ); - } - - public function testEmailWellKnownUserAtHostDotTldAreValid() { - $this->valid( 'user@example.com' ); - $this->valid( 'user@example.museum' ); - } - - public function testEmailWithUpperCaseCharactersAreValid() { - $this->valid( 'USER@example.com' ); - $this->valid( 'user@EXAMPLE.COM' ); - $this->valid( 'user@Example.com' ); - $this->valid( 'USER@eXAMPLE.com' ); - } - - public function testEmailWithAPlusInUserName() { - $this->valid( 'user+sub@example.com' ); - $this->valid( 'user+@example.com' ); - } - - public function testEmailDoesNotNeedATopLevelDomain() { - $this->valid( "user@localhost" ); - $this->valid( "FooBar@localdomain" ); - $this->valid( "nobody@mycompany" ); - } - - public function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { - $this->invalid( " user@host.com" ); - $this->invalid( "user@host.com " ); - $this->invalid( "\tuser@host.com" ); - $this->invalid( "user@host.com\t" ); - } - - public function testEmailWithWhiteSpacesAreInvalids() { - $this->invalid( "User user@host" ); - $this->invalid( "first last@mycompany" ); - $this->invalid( "firstlast@my company" ); - } - - /** - * T28948 : comma were matched by an incorrect regexp range - */ - public function testEmailWithCommasAreInvalids() { - $this->invalid( "user,foo@example.org" ); - $this->invalid( "userfoo@ex,ample.org" ); - } - - public function testEmailWithHyphens() { - $this->valid( "user-foo@example.org" ); - $this->valid( "userfoo@ex-ample.org" ); - } - - public function testEmailDomainCanNotBeginWithDot() { - $this->invalid( "user@." ); - $this->invalid( "user@.localdomain" ); - $this->invalid( "user@localdomain." ); - $this->valid( "user.@localdomain" ); - $this->valid( ".@localdomain" ); - $this->invalid( ".@a............" ); - } - - public function testEmailWithFunnyCharacters() { - $this->valid( "\$user!ex{this}@123.com" ); - } - - public function testEmailTopLevelDomainCanBeNumerical() { - $this->valid( "user@example.1234" ); - } - - public function testEmailWithoutAtSignIsInvalid() { - $this->invalid( 'useràexample.com' ); - } - - public function testEmailWithOneCharacterDomainIsValid() { - $this->valid( 'user@a' ); - } -} diff --git a/tests/phpunit/includes/XmlJsTest.php b/tests/phpunit/includes/XmlJsTest.php deleted file mode 100644 index c7975efabc..0000000000 --- a/tests/phpunit/includes/XmlJsTest.php +++ /dev/null @@ -1,26 +0,0 @@ -assertEquals( $value, $obj->value ); - } - - public static function provideConstruction() { - return [ - [ null ], - [ '' ], - ]; - } - -} diff --git a/tests/phpunit/includes/composer/ComposerVersionNormalizerTest.php b/tests/phpunit/includes/composer/ComposerVersionNormalizerTest.php deleted file mode 100644 index c5c0dc7d6b..0000000000 --- a/tests/phpunit/includes/composer/ComposerVersionNormalizerTest.php +++ /dev/null @@ -1,163 +0,0 @@ - - */ -class ComposerVersionNormalizerTest extends PHPUnit\Framework\TestCase { - - use MediaWikiCoversValidator; - use PHPUnit4And6Compat; - - /** - * @dataProvider nonStringProvider - */ - public function testGivenNonString_normalizeThrowsInvalidArgumentException( $nonString ) { - $normalizer = new ComposerVersionNormalizer(); - - $this->setExpectedException( InvalidArgumentException::class ); - $normalizer->normalizeSuffix( $nonString ); - } - - public function nonStringProvider() { - return [ - [ null ], - [ 42 ], - [ [] ], - [ new stdClass() ], - [ true ], - ]; - } - - /** - * @dataProvider simpleVersionProvider - */ - public function testGivenSimpleVersion_normalizeSuffixReturnsAsIs( $simpleVersion ) { - $this->assertRemainsUnchanged( $simpleVersion ); - } - - protected function assertRemainsUnchanged( $version ) { - $normalizer = new ComposerVersionNormalizer(); - - $this->assertEquals( - $version, - $normalizer->normalizeSuffix( $version ) - ); - } - - public function simpleVersionProvider() { - return [ - [ '1.22.0' ], - [ '1.19.2' ], - [ '1.19.2.0' ], - [ '1.9' ], - [ '123.321.456.654' ], - ]; - } - - /** - * @dataProvider complexVersionProvider - */ - public function testGivenComplexVersionWithoutDash_normalizeSuffixAddsDash( - $withoutDash, $withDash - ) { - $normalizer = new ComposerVersionNormalizer(); - - $this->assertEquals( - $withDash, - $normalizer->normalizeSuffix( $withoutDash ) - ); - } - - public function complexVersionProvider() { - return [ - [ '1.22.0alpha', '1.22.0-alpha' ], - [ '1.22.0RC', '1.22.0-RC' ], - [ '1.19beta', '1.19-beta' ], - [ '1.9RC4', '1.9-RC4' ], - [ '1.9.1.2RC4', '1.9.1.2-RC4' ], - [ '1.9.1.2RC', '1.9.1.2-RC' ], - [ '123.321.456.654RC9001', '123.321.456.654-RC9001' ], - ]; - } - - /** - * @dataProvider complexVersionProvider - */ - public function testGivenComplexVersionWithDash_normalizeSuffixReturnsAsIs( - $withoutDash, $withDash - ) { - $this->assertRemainsUnchanged( $withDash ); - } - - /** - * @dataProvider fourLevelVersionsProvider - */ - public function testGivenFourLevels_levelCountNormalizationDoesNothing( $version ) { - $normalizer = new ComposerVersionNormalizer(); - - $this->assertEquals( - $version, - $normalizer->normalizeLevelCount( $version ) - ); - } - - public function fourLevelVersionsProvider() { - return [ - [ '1.22.0.0' ], - [ '1.19.2.4' ], - [ '1.19.2.0' ], - [ '1.9.0.1' ], - [ '123.321.456.654' ], - [ '123.321.456.654RC4' ], - [ '123.321.456.654-RC4' ], - ]; - } - - /** - * @dataProvider levelNormalizationProvider - */ - public function testGivenFewerLevels_levelCountNormalizationEnsuresFourLevels( - $expected, $version - ) { - $normalizer = new ComposerVersionNormalizer(); - - $this->assertEquals( - $expected, - $normalizer->normalizeLevelCount( $version ) - ); - } - - public function levelNormalizationProvider() { - return [ - [ '1.22.0.0', '1.22' ], - [ '1.22.0.0', '1.22.0' ], - [ '1.19.2.0', '1.19.2' ], - [ '12345.0.0.0', '12345' ], - [ '12345.0.0.0-RC4', '12345-RC4' ], - [ '12345.0.0.0-alpha', '12345-alpha' ], - ]; - } - - /** - * @dataProvider invalidVersionProvider - */ - public function testGivenInvalidVersion_normalizeSuffixReturnsAsIs( $invalidVersion ) { - $this->assertRemainsUnchanged( $invalidVersion ); - } - - public function invalidVersionProvider() { - return [ - [ '1.221-a' ], - [ '1.221-' ], - [ '1.22rc4a' ], - [ 'a1.22rc' ], - [ '.1.22rc' ], - [ 'a' ], - [ 'alpha42' ], - ]; - } -} diff --git a/tests/phpunit/includes/config/EtcdConfigTest.php b/tests/phpunit/includes/config/EtcdConfigTest.php deleted file mode 100644 index 3eecf82704..0000000000 --- a/tests/phpunit/includes/config/EtcdConfigTest.php +++ /dev/null @@ -1,621 +0,0 @@ -getMockBuilder( EtcdConfig::class ) - ->setConstructorArgs( [ $options + [ - 'host' => 'etcd-tcp.example.net', - 'directory' => '/', - 'timeout' => 0.1, - ] ] ) - ->setMethods( [ 'fetchAllFromEtcd' ] ) - ->getMock(); - } - - private static function createEtcdResponse( array $response ) { - $baseResponse = [ - 'config' => null, - 'error' => null, - 'retry' => false, - 'modifiedIndex' => 0, - ]; - return array_merge( $baseResponse, $response ); - } - - private function createSimpleConfigMock( array $config, $index = 0 ) { - $mock = $this->createConfigMock(); - $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( self::createEtcdResponse( [ - 'config' => $config, - 'modifiedIndex' => $index, - ] ) ); - return $mock; - } - - /** - * @covers EtcdConfig::has - */ - public function testHasKnown() { - $config = $this->createSimpleConfigMock( [ - 'known' => 'value' - ] ); - $this->assertSame( true, $config->has( 'known' ) ); - } - - /** - * @covers EtcdConfig::__construct - * @covers EtcdConfig::get - */ - public function testGetKnown() { - $config = $this->createSimpleConfigMock( [ - 'known' => 'value' - ] ); - $this->assertSame( 'value', $config->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::has - */ - public function testHasUnknown() { - $config = $this->createSimpleConfigMock( [ - 'known' => 'value' - ] ); - $this->assertSame( false, $config->has( 'unknown' ) ); - } - - /** - * @covers EtcdConfig::get - */ - public function testGetUnknown() { - $config = $this->createSimpleConfigMock( [ - 'known' => 'value' - ] ); - $this->setExpectedException( ConfigException::class ); - $config->get( 'unknown' ); - } - - /** - * @covers EtcdConfig::getModifiedIndex - */ - public function testGetModifiedIndex() { - $config = $this->createSimpleConfigMock( - [ 'some' => 'value' ], - 123 - ); - $this->assertSame( 123, $config->getModifiedIndex() ); - } - - /** - * @covers EtcdConfig::__construct - */ - public function testConstructCacheObj() { - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' ) - ->willReturn( [ - 'config' => [ 'known' => 'from-cache' ], - 'expires' => INF, - 'modifiedIndex' => 123 - ] ); - $config = $this->createConfigMock( [ 'cache' => $cache ] ); - - $this->assertSame( 'from-cache', $config->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::__construct - */ - public function testConstructCacheSpec() { - $config = $this->createConfigMock( [ 'cache' => [ - 'class' => HashBagOStuff::class - ] ] ); - $config->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( self::createEtcdResponse( - [ 'config' => [ 'known' => 'from-fetch' ], ] ) ); - - $this->assertSame( 'from-fetch', $config->get( 'known' ) ); - } - - /** - * Test matrix - * - * - [x] Cache miss - * Result: Fetched value - * > cache miss | gets lock | backend succeeds - * - * - [x] Cache miss with backend error - * Result: ConfigException - * > cache miss | gets lock | backend error (no retry) - * - * - [x] Cache hit after retry - * Result: Cached value (populated by process holding lock) - * > cache miss | no lock | cache retry - * - * - [x] Cache hit - * Result: Cached value - * > cache hit - * - * - [x] Process cache hit - * Result: Cached value - * > process cache hit - * - * - [x] Cache expired - * Result: Fetched value - * > cache expired | gets lock | backend succeeds - * - * - [x] Cache expired with backend failure - * Result: Cached value (stale) - * > cache expired | gets lock | backend fails (allows retry) - * - * - [x] Cache expired and no lock - * Result: Cached value (stale) - * > cache expired | no lock - * - * Other notable scenarios: - * - * - [ ] Cache miss with backend retry - * Result: Fetched value - * > cache expired | gets lock | backend failure (allows retry) - */ - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheMiss() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - // .. misses cache - $cache->expects( $this->once() )->method( 'get' ) - ->willReturn( false ); - // .. gets lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( true ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( - self::createEtcdResponse( [ 'config' => [ 'known' => 'from-fetch' ] ] ) ); - - $this->assertSame( 'from-fetch', $mock->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheMissBackendError() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - // .. misses cache - $cache->expects( $this->once() )->method( 'get' ) - ->willReturn( false ); - // .. gets lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( true ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( self::createEtcdResponse( [ 'error' => 'Fake error', ] ) ); - - $this->setExpectedException( ConfigException::class ); - $mock->get( 'key' ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheMissWithoutLock() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->exactly( 2 ) )->method( 'get' ) - ->will( $this->onConsecutiveCalls( - // .. misses cache first time - false, - // .. hits cache on retry - [ - 'config' => [ 'known' => 'from-cache' ], - 'expires' => INF, - 'modifiedIndex' => 123 - ] - ) ); - // .. misses lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( false ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->never() )->method( 'fetchAllFromEtcd' ); - - $this->assertSame( 'from-cache', $mock->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheHit() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' ) - // .. hits cache - ->willReturn( [ - 'config' => [ 'known' => 'from-cache' ], - 'expires' => INF, - 'modifiedIndex' => 0, - ] ); - $cache->expects( $this->never() )->method( 'lock' ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->never() )->method( 'fetchAllFromEtcd' ); - - $this->assertSame( 'from-cache', $mock->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadProcessCacheHit() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' ) - // .. hits cache - ->willReturn( [ - 'config' => [ 'known' => 'from-cache' ], - 'expires' => INF, - 'modifiedIndex' => 0, - ] ); - $cache->expects( $this->never() )->method( 'lock' ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->never() )->method( 'fetchAllFromEtcd' ); - - $this->assertSame( 'from-cache', $mock->get( 'known' ), 'Cache hit' ); - $this->assertSame( 'from-cache', $mock->get( 'known' ), 'Process cache hit' ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheExpiredLockFetchSucceeded() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' )->willReturn( - // .. stale cache - [ - 'config' => [ 'known' => 'from-cache-expired' ], - 'expires' => -INF, - 'modifiedIndex' => 0, - ] - ); - // .. gets lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( true ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( self::createEtcdResponse( [ 'config' => [ 'known' => 'from-fetch' ] ] ) ); - - $this->assertSame( 'from-fetch', $mock->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheExpiredLockFetchFails() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' )->willReturn( - // .. stale cache - [ - 'config' => [ 'known' => 'from-cache-expired' ], - 'expires' => -INF, - 'modifiedIndex' => 0, - ] - ); - // .. gets lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( true ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->once() )->method( 'fetchAllFromEtcd' ) - ->willReturn( self::createEtcdResponse( [ 'error' => 'Fake failure', 'retry' => true ] ) ); - - $this->assertSame( 'from-cache-expired', $mock->get( 'known' ) ); - } - - /** - * @covers EtcdConfig::load - */ - public function testLoadCacheExpiredNoLock() { - // Create cache mock - $cache = $this->getMockBuilder( HashBagOStuff::class ) - ->setMethods( [ 'get', 'lock' ] ) - ->getMock(); - $cache->expects( $this->once() )->method( 'get' ) - // .. hits cache (expired value) - ->willReturn( [ - 'config' => [ 'known' => 'from-cache-expired' ], - 'expires' => -INF, - 'modifiedIndex' => 0, - ] ); - // .. misses lock - $cache->expects( $this->once() )->method( 'lock' ) - ->willReturn( false ); - - // Create config mock - $mock = $this->createConfigMock( [ - 'cache' => $cache, - ] ); - $mock->expects( $this->never() )->method( 'fetchAllFromEtcd' ); - - $this->assertSame( 'from-cache-expired', $mock->get( 'known' ) ); - } - - public static function provideFetchFromServer() { - return [ - '200 OK - Success' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/foo', - 'value' => json_encode( [ 'val' => true ] ), - 'modifiedIndex' => 123 - ], - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'config' => [ 'foo' => true ], // data - 'modifiedIndex' => 123 - ] ), - ], - '200 OK - Empty dir' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/foo', - 'value' => json_encode( [ 'val' => true ] ), - 'modifiedIndex' => 123 - ], - [ - 'key' => '/example/sub', - 'dir' => true, - 'modifiedIndex' => 234, - 'nodes' => [], - ], - [ - 'key' => '/example/bar', - 'value' => json_encode( [ 'val' => false ] ), - 'modifiedIndex' => 125 - ], - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'config' => [ 'foo' => true, 'bar' => false ], // data - 'modifiedIndex' => 125 // largest modified index - ] ), - ], - '200 OK - Recursive' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/a', - 'dir' => true, - 'modifiedIndex' => 124, - 'nodes' => [ - [ - 'key' => 'b', - 'value' => json_encode( [ 'val' => true ] ), - 'modifiedIndex' => 123, - - ], - [ - 'key' => 'c', - 'value' => json_encode( [ 'val' => false ] ), - 'modifiedIndex' => 123, - ], - ], - ], - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'config' => [ 'a/b' => true, 'a/c' => false ], // data - 'modifiedIndex' => 123 // largest modified index - ] ), - ], - '200 OK - Missing nodes at second level' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/a', - 'dir' => true, - 'modifiedIndex' => 0, - ], - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => "Unexpected JSON response in dir 'a'; missing 'nodes' list.", - ] ), - ], - '200 OK - Directory with non-array "nodes" key' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/a', - 'dir' => true, - 'nodes' => 'not an array' - ], - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => "Unexpected JSON response in dir 'a'; 'nodes' is not an array.", - ] ), - ], - '200 OK - Correctly encoded garbage response' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'foo' => 'bar' ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => "Unexpected JSON response: Missing or invalid node at top level.", - ] ), - ], - '200 OK - Bad value' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => json_encode( [ 'node' => [ 'nodes' => [ - [ - 'key' => '/example/foo', - 'value' => ';"broken{value', - 'modifiedIndex' => 123, - ] - ] ] ] ), - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => "Failed to parse value for 'foo'.", - ] ), - ], - '200 OK - Empty node list' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [], - 'body' => '{"node":{"nodes":[], "modifiedIndex": 12 }}', - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'config' => [], // data - ] ), - ], - '200 OK - Invalid JSON' => [ - 'http' => [ - 'code' => 200, - 'reason' => 'OK', - 'headers' => [ 'content-length' => 0 ], - 'body' => '', - 'error' => '(curl error: no status set)', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => "Error unserializing JSON response.", - ] ), - ], - '404 Not Found' => [ - 'http' => [ - 'code' => 404, - 'reason' => 'Not Found', - 'headers' => [ 'content-length' => 0 ], - 'body' => '', - 'error' => '', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => 'HTTP 404 (Not Found)', - ] ), - ], - '400 Bad Request - custom error' => [ - 'http' => [ - 'code' => 400, - 'reason' => 'Bad Request', - 'headers' => [ 'content-length' => 0 ], - 'body' => '', - 'error' => 'No good reason', - ], - 'expect' => self::createEtcdResponse( [ - 'error' => 'No good reason', - 'retry' => true, // retry - ] ), - ], - ]; - } - - /** - * @covers EtcdConfig::fetchAllFromEtcdServer - * @covers EtcdConfig::unserialize - * @covers EtcdConfig::parseResponse - * @covers EtcdConfig::parseDirectory - * @covers EtcdConfigParseError - * @dataProvider provideFetchFromServer - */ - public function testFetchFromServer( array $httpResponse, array $expected ) { - $http = $this->getMockBuilder( MultiHttpClient::class ) - ->disableOriginalConstructor() - ->getMock(); - $http->expects( $this->once() )->method( 'run' ) - ->willReturn( array_values( $httpResponse ) ); - - $conf = $this->getMockBuilder( EtcdConfig::class ) - ->disableOriginalConstructor() - ->getMock(); - // Access for protected member and method - $conf = TestingAccessWrapper::newFromObject( $conf ); - $conf->http = $http; - - $this->assertSame( - $expected, - $conf->fetchAllFromEtcdServer( 'etcd-tcp.example.net' ) - ); - } -} diff --git a/tests/phpunit/includes/db/DatabaseOracleTest.php b/tests/phpunit/includes/db/DatabaseOracleTest.php deleted file mode 100644 index 061e121a24..0000000000 --- a/tests/phpunit/includes/db/DatabaseOracleTest.php +++ /dev/null @@ -1,52 +0,0 @@ -getMockBuilder( DatabaseOracle::class ) - ->disableOriginalConstructor() - ->setMethods( null ) - ->getMock(); - } - - public function provideBuildSubstring() { - yield [ 'someField', 1, 2, 'SUBSTR(someField,1,2)' ]; - yield [ 'someField', 1, null, 'SUBSTR(someField,1)' ]; - } - - /** - * @covers DatabaseOracle::buildSubstring - * @dataProvider provideBuildSubstring - */ - public function testBuildSubstring( $input, $start, $length, $expected ) { - $mockDb = $this->getMockDb(); - $output = $mockDb->buildSubstring( $input, $start, $length ); - $this->assertSame( $expected, $output ); - } - - public function provideBuildSubstring_invalidParams() { - yield [ -1, 1 ]; - yield [ 1, -1 ]; - yield [ 1, 'foo' ]; - yield [ 'foo', 1 ]; - yield [ null, 1 ]; - yield [ 0, 1 ]; - } - - /** - * @covers DatabaseOracle::buildSubstring - * @dataProvider provideBuildSubstring_invalidParams - */ - public function testBuildSubstring_invalidParams( $start, $length ) { - $mockDb = $this->getMockDb(); - $this->setExpectedException( InvalidArgumentException::class ); - $mockDb->buildSubstring( 'foo', $start, $length ); - } - -} diff --git a/tests/phpunit/includes/debug/logger/monolog/LogstashFormatterTest.php b/tests/phpunit/includes/debug/logger/monolog/LogstashFormatterTest.php deleted file mode 100644 index a1207b26b2..0000000000 --- a/tests/phpunit/includes/debug/logger/monolog/LogstashFormatterTest.php +++ /dev/null @@ -1,59 +0,0 @@ -format( $record ), true ); - foreach ( $expected as $key => $value ) { - $this->assertArrayHasKey( $key, $formatted ); - $this->assertSame( $value, $formatted[$key] ); - } - foreach ( $notExpected as $key ) { - $this->assertArrayNotHasKey( $key, $formatted ); - } - } - - public function provideV1() { - return [ - [ - [ 'extra' => [ 'foo' => 1 ], 'context' => [ 'bar' => 2 ] ], - [ 'foo' => 1, 'bar' => 2 ], - [ 'logstash_formatter_key_conflict' ], - ], - [ - [ 'extra' => [ 'url' => 1 ], 'context' => [ 'url' => 2 ] ], - [ 'url' => 1, 'c_url' => 2, 'logstash_formatter_key_conflict' => [ 'url' ] ], - [], - ], - [ - [ 'channel' => 'x', 'context' => [ 'channel' => 'y' ] ], - [ 'channel' => 'x', 'c_channel' => 'y', - 'logstash_formatter_key_conflict' => [ 'channel' ] ], - [], - ], - ]; - } - - /** - * @covers MediaWiki\Logger\Monolog\LogstashFormatter::formatV1 - */ - public function testV1WithPrefix() { - $formatter = new LogstashFormatter( 'app', 'system', null, 'ctx_', LogstashFormatter::V1 ); - $record = [ 'extra' => [ 'url' => 1 ], 'context' => [ 'url' => 2 ] ]; - $formatted = json_decode( $formatter->format( $record ), true ); - $this->assertArrayHasKey( 'url', $formatted ); - $this->assertSame( 1, $formatted['url'] ); - $this->assertArrayHasKey( 'ctx_url', $formatted ); - $this->assertSame( 2, $formatted['ctx_url'] ); - $this->assertArrayNotHasKey( 'c_url', $formatted ); - } -} diff --git a/tests/phpunit/includes/deferred/MWCallableUpdateTest.php b/tests/phpunit/includes/deferred/MWCallableUpdateTest.php deleted file mode 100644 index 3ab9b5659e..0000000000 --- a/tests/phpunit/includes/deferred/MWCallableUpdateTest.php +++ /dev/null @@ -1,82 +0,0 @@ -assertSame( 0, $ran ); - $update->doUpdate(); - $this->assertSame( 1, $ran ); - } - - public function testCancel() { - // Prepare update and DB - $db = new DatabaseTestHelper( __METHOD__ ); - $db->begin( __METHOD__ ); - $ran = 0; - $update = new MWCallableUpdate( function () use ( &$ran ) { - $ran++; - }, __METHOD__, $db ); - - // Emulate rollback - $db->rollback( __METHOD__ ); - - $update->doUpdate(); - - // Ensure it was cancelled - $this->assertSame( 0, $ran ); - } - - public function testCancelSome() { - // Prepare update and DB - $db1 = new DatabaseTestHelper( __METHOD__ ); - $db1->begin( __METHOD__ ); - $db2 = new DatabaseTestHelper( __METHOD__ ); - $db2->begin( __METHOD__ ); - $ran = 0; - $update = new MWCallableUpdate( function () use ( &$ran ) { - $ran++; - }, __METHOD__, [ $db1, $db2 ] ); - - // Emulate rollback - $db1->rollback( __METHOD__ ); - - $update->doUpdate(); - - // Prevents: "Notice: DB transaction writes or callbacks still pending" - $db2->rollback( __METHOD__ ); - - // Ensure it was cancelled - $this->assertSame( 0, $ran ); - } - - public function testCancelAll() { - // Prepare update and DB - $db1 = new DatabaseTestHelper( __METHOD__ ); - $db1->begin( __METHOD__ ); - $db2 = new DatabaseTestHelper( __METHOD__ ); - $db2->begin( __METHOD__ ); - $ran = 0; - $update = new MWCallableUpdate( function () use ( &$ran ) { - $ran++; - }, __METHOD__, [ $db1, $db2 ] ); - - // Emulate rollbacks - $db1->rollback( __METHOD__ ); - $db2->rollback( __METHOD__ ); - - $update->doUpdate(); - - // Ensure it was cancelled - $this->assertSame( 0, $ran ); - } - -} diff --git a/tests/phpunit/includes/deferred/TransactionRoundDefiningUpdateTest.php b/tests/phpunit/includes/deferred/TransactionRoundDefiningUpdateTest.php deleted file mode 100644 index 693897e676..0000000000 --- a/tests/phpunit/includes/deferred/TransactionRoundDefiningUpdateTest.php +++ /dev/null @@ -1,19 +0,0 @@ -assertSame( 0, $ran ); - $update->doUpdate(); - $this->assertSame( 1, $ran ); - } -} diff --git a/tests/phpunit/includes/objectcache/RedisBagOStuffTest.php b/tests/phpunit/includes/objectcache/RedisBagOStuffTest.php deleted file mode 100644 index df5614d8c1..0000000000 --- a/tests/phpunit/includes/objectcache/RedisBagOStuffTest.php +++ /dev/null @@ -1,110 +0,0 @@ -getMockBuilder( RedisBagOStuff::class ) - ->disableOriginalConstructor() - ->getMock(); - $this->cache = TestingAccessWrapper::newFromObject( $cache ); - } - - /** - * @covers RedisBagOStuff::unserialize - * @dataProvider unserializeProvider - */ - public function testUnserialize( $expected, $input, $message ) { - $actual = $this->cache->unserialize( $input ); - $this->assertSame( $expected, $actual, $message ); - } - - public function unserializeProvider() { - return [ - [ - -1, - '-1', - 'String representation of \'-1\'', - ], - [ - 0, - '0', - 'String representation of \'0\'', - ], - [ - 1, - '1', - 'String representation of \'1\'', - ], - [ - -1.0, - 'd:-1;', - 'Serialized negative double', - ], - [ - 'foo', - 's:3:"foo";', - 'Serialized string', - ] - ]; - } - - /** - * @covers RedisBagOStuff::serialize - * @dataProvider serializeProvider - */ - public function testSerialize( $expected, $input, $message ) { - $actual = $this->cache->serialize( $input ); - $this->assertSame( $expected, $actual, $message ); - } - - public function serializeProvider() { - return [ - [ - -1, - -1, - '-1 as integer', - ], - [ - 0, - 0, - '0 as integer', - ], - [ - 1, - 1, - '1 as integer', - ], - [ - 'd:-1;', - -1.0, - 'Negative double', - ], - [ - 's:3:"2.1";', - '2.1', - 'Decimal string', - ], - [ - 's:1:"1";', - '1', - 'String representation of 1', - ], - [ - 's:3:"foo";', - 'foo', - 'String', - ], - ]; - } -} diff --git a/tests/phpunit/includes/registration/VersionCheckerTest.php b/tests/phpunit/includes/registration/VersionCheckerTest.php deleted file mode 100644 index e824e3f02c..0000000000 --- a/tests/phpunit/includes/registration/VersionCheckerTest.php +++ /dev/null @@ -1,479 +0,0 @@ -assertEquals( $expected, !(bool)$checker->checkArray( [ - 'FakeExtension' => [ - 'MediaWiki' => $constraint, - ], - ] ) ); - } - - public static function provideMediaWikiCheck() { - return [ - // [ $wgVersion, constraint, expected ] - [ '1.25alpha', '>= 1.26', false ], - [ '1.25.0', '>= 1.26', false ], - [ '1.26alpha', '>= 1.26', true ], - [ '1.26alpha', '>= 1.26.0', true ], - [ '1.26alpha', '>= 1.26.0-stable', false ], - [ '1.26.0', '>= 1.26.0-stable', true ], - [ '1.26.1', '>= 1.26.0-stable', true ], - [ '1.27.1', '>= 1.26.0-stable', true ], - [ '1.26alpha', '>= 1.26.1', false ], - [ '1.26alpha', '>= 1.26alpha', true ], - [ '1.26alpha', '>= 1.25', true ], - [ '1.26.0-alpha.14', '>= 1.26.0-alpha.15', false ], - [ '1.26.0-alpha.14', '>= 1.26.0-alpha.10', true ], - [ '1.26.1', '>= 1.26.2, <=1.26.0', false ], - [ '1.26.1', '^1.26.2', false ], - // Accept anything for un-parsable version strings - [ '1.26mwf14', '== 1.25alpha', true ], - [ 'totallyinvalid', '== 1.0', true ], - ]; - } - - /** - * @dataProvider providePhpValidCheck - */ - public function testPhpValidCheck( $phpVersion, $constraint, $expected ) { - $checker = new VersionChecker( '1.0.0', $phpVersion, [] ); - $this->assertEquals( $expected, !(bool)$checker->checkArray( [ - 'FakeExtension' => [ - 'platform' => [ - 'php' => $constraint, - ], - ], - ] ) ); - } - - public static function providePhpValidCheck() { - return [ - // [ phpVersion, constraint, expected ] - [ '7.0.23', '>= 7.0.0', true ], - [ '7.0.23', '^7.1.0', false ], - [ '7.0.23', '7.0.23', true ], - ]; - } - - /** - * @expectedException UnexpectedValueException - */ - public function testPhpInvalidConstraint() { - $checker = new VersionChecker( '1.0.0', '7.0.0', [] ); - $checker->checkArray( [ - 'FakeExtension' => [ - 'platform' => [ - 'php' => 'totallyinvalid', - ], - ], - ] ); - } - - /** - * @dataProvider providePhpInvalidVersion - * @expectedException UnexpectedValueException - */ - public function testPhpInvalidVersion( $phpVersion ) { - $checker = new VersionChecker( '1.0.0', $phpVersion, [] ); - } - - public static function providePhpInvalidVersion() { - return [ - // [ phpVersion ] - [ '7.abc' ], - [ '5.a.x' ], - ]; - } - - /** - * @dataProvider provideType - */ - public function testType( $given, $expected ) { - $checker = new VersionChecker( - '1.0.0', - '7.0.0', - [ 'phpLoadedExtension' ], - [ - 'presentAbility' => true, - 'presentAbilityWithMessage' => true, - 'missingAbility' => false, - 'missingAbilityWithMessage' => false, - ], - [ - 'presentAbilityWithMessage' => 'Present.', - 'missingAbilityWithMessage' => 'Missing.', - ] - ); - $checker->setLoadedExtensionsAndSkins( [ - 'FakeDependency' => [ - 'version' => '1.0.0', - ], - 'NoVersionGiven' => [], - ] ); - $this->assertEquals( $expected, $checker->checkArray( [ - 'FakeExtension' => $given, - ] ) ); - } - - public static function provideType() { - return [ - // valid type - [ - [ - 'extensions' => [ - 'FakeDependency' => '1.0.0', - ], - ], - [], - ], - [ - [ - 'MediaWiki' => '1.0.0', - ], - [], - ], - [ - [ - 'extensions' => [ - 'NoVersionGiven' => '*', - ], - ], - [], - ], - [ - [ - 'extensions' => [ - 'NoVersionGiven' => '1.0', - ], - ], - [ - [ - 'incompatible' => 'FakeExtension', - 'type' => 'incompatible-extensions', - 'msg' => 'NoVersionGiven does not expose its version, but FakeExtension requires: 1.0.', - ], - ], - ], - [ - [ - 'extensions' => [ - 'Missing' => '*', - ], - ], - [ - [ - 'missing' => 'Missing', - 'type' => 'missing-extensions', - 'msg' => 'FakeExtension requires Missing to be installed.', - ], - ], - ], - [ - [ - 'extensions' => [ - 'FakeDependency' => '2.0.0', - ], - ], - [ - [ - 'incompatible' => 'FakeExtension', - 'type' => 'incompatible-extensions', - // phpcs:ignore Generic.Files.LineLength.TooLong - 'msg' => 'FakeExtension is not compatible with the current installed version of FakeDependency (1.0.0), it requires: 2.0.0.', - ], - ], - ], - [ - [ - 'skins' => [ - 'FakeSkin' => '*', - ], - ], - [ - [ - 'missing' => 'FakeSkin', - 'type' => 'missing-skins', - 'msg' => 'FakeExtension requires FakeSkin to be installed.', - ], - ], - ], - [ - [ - 'platform' => [ - 'ext-phpLoadedExtension' => '*', - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ext-phpMissingExtension' => '*', - ], - ], - [ - [ - 'missing' => 'phpMissingExtension', - 'type' => 'missing-phpExtension', - // phpcs:ignore Generic.Files.LineLength.TooLong - 'msg' => 'FakeExtension requires phpMissingExtension PHP extension to be installed.', - ], - ], - ], - [ - [ - 'platform' => [ - 'ability-presentAbility' => true, - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ability-presentAbilityWithMessage' => true, - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ability-presentAbility' => false, - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ability-presentAbilityWithMessage' => false, - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ability-missingAbility' => true, - ], - ], - [ - [ - 'missing' => 'missingAbility', - 'type' => 'missing-ability', - 'msg' => 'FakeExtension requires "missingAbility" ability', - ], - ], - ], - [ - [ - 'platform' => [ - 'ability-missingAbilityWithMessage' => true, - ], - ], - [ - [ - 'missing' => 'missingAbilityWithMessage', - 'type' => 'missing-ability', - // phpcs:ignore Generic.Files.LineLength.TooLong - 'msg' => 'FakeExtension requires "missingAbilityWithMessage" ability: Missing.', - ], - ], - ], - [ - [ - 'platform' => [ - 'ability-missingAbility' => false, - ], - ], - [], - ], - [ - [ - 'platform' => [ - 'ability-missingAbilityWithMessage' => false, - ], - ], - [], - ], - ]; - } - - /** - * Check, if a non-parsable version constraint does not throw an exception or - * returns any error message. - */ - public function testInvalidConstraint() { - $checker = new VersionChecker( '1.0.0', '7.0.0', [] ); - $checker->setLoadedExtensionsAndSkins( [ - 'FakeDependency' => [ - 'version' => 'not really valid', - ], - ] ); - $this->assertEquals( [ - [ - 'type' => 'invalid-version', - 'msg' => "FakeDependency does not have a valid version string.", - ], - ], $checker->checkArray( [ - 'FakeExtension' => [ - 'extensions' => [ - 'FakeDependency' => '1.24.3', - ], - ], - ] ) ); - - $checker = new VersionChecker( '1.0.0', '7.0.0', [] ); - $checker->setLoadedExtensionsAndSkins( [ - 'FakeDependency' => [ - 'version' => '1.24.3', - ], - ] ); - - $this->setExpectedException( UnexpectedValueException::class ); - $checker->checkArray( [ - 'FakeExtension' => [ - 'FakeDependency' => 'not really valid', - ], - ] ); - } - - public function provideInvalidDependency() { - return [ - [ - [ - 'FakeExtension' => [ - 'platform' => [ - 'undefinedPlatformDependency' => '*', - ], - ], - ], - 'undefinedPlatformDependency', - ], - [ - [ - 'FakeExtension' => [ - 'platform' => [ - 'phpLoadedExtension' => '*', - ], - ], - ], - 'phpLoadedExtension', - ], - [ - [ - 'FakeExtension' => [ - 'platform' => [ - 'ability-invalidAbility' => true, - ], - ], - ], - 'ability-invalidAbility', - ], - [ - [ - 'FakeExtension' => [ - 'platform' => [ - 'presentAbility' => true, - ], - ], - ], - 'presentAbility', - ], - [ - [ - 'FakeExtension' => [ - 'undefinedDependencyType' => '*', - ], - ], - 'undefinedDependencyType', - ], - // T197478 - [ - [ - 'FakeExtension' => [ - 'skin' => [ - 'FakeSkin' => '*', - ], - ], - ], - 'skin', - ], - ]; - } - - /** - * @dataProvider provideInvalidDependency - */ - public function testInvalidDependency( $depencency, $type ) { - $checker = new VersionChecker( - '1.0.0', - '7.0.0', - [ 'phpLoadedExtension' ], - [ - 'presentAbility' => true, - 'missingAbility' => false, - ] - ); - $this->setExpectedException( - UnexpectedValueException::class, - "Dependency type $type unknown in FakeExtension" - ); - $checker->checkArray( $depencency ); - } - - public function testInvalidPhpExtensionConstraint() { - $checker = new VersionChecker( '1.0.0', '7.0.0', [ 'phpLoadedExtension' ] ); - $this->setExpectedException( - UnexpectedValueException::class, - 'Version constraints for PHP extensions are not supported in FakeExtension' - ); - $checker->checkArray( [ - 'FakeExtension' => [ - 'platform' => [ - 'ext-phpLoadedExtension' => '1.0.0', - ], - ], - ] ); - } - - /** - * @dataProvider provideInvalidAbilityType - */ - public function testInvalidAbilityType( $value ) { - $checker = new VersionChecker( '1.0.0', '7.0.0', [], [ 'presentAbility' => true ] ); - $this->setExpectedException( - UnexpectedValueException::class, - 'Only booleans are allowed to to indicate the presence of abilities in FakeExtension' - ); - $checker->checkArray( [ - 'FakeExtension' => [ - 'platform' => [ - 'ability-presentAbility' => $value, - ], - ], - ] ); - } - - public function provideInvalidAbilityType() { - return [ - [ null ], - [ 1 ], - [ '1' ], - ]; - } - -} diff --git a/tests/phpunit/includes/search/SearchSuggestionSetTest.php b/tests/phpunit/includes/search/SearchSuggestionSetTest.php deleted file mode 100644 index 02fa5e9cac..0000000000 --- a/tests/phpunit/includes/search/SearchSuggestionSetTest.php +++ /dev/null @@ -1,111 +0,0 @@ -assertEquals( 0, $set->getSize() ); - $set->append( new SearchSuggestion( 3 ) ); - $this->assertEquals( 3, $set->getWorstScore() ); - $this->assertEquals( 3, $set->getBestScore() ); - - $suggestion = new SearchSuggestion( 4 ); - $set->append( $suggestion ); - $this->assertEquals( 2, $set->getWorstScore() ); - $this->assertEquals( 3, $set->getBestScore() ); - $this->assertEquals( 2, $suggestion->getScore() ); - - $suggestion = new SearchSuggestion( 2 ); - $set->append( $suggestion ); - $this->assertEquals( 1, $set->getWorstScore() ); - $this->assertEquals( 3, $set->getBestScore() ); - $this->assertEquals( 1, $suggestion->getScore() ); - - $scores = $set->map( function ( $s ) { - return $s->getScore(); - } ); - $sorted = $scores; - asort( $sorted ); - $this->assertEquals( $sorted, $scores ); - } - - /** - * Test that adding a new best suggestion will keep proper score - * ordering - * @covers SearchSuggestionSet::getWorstScore - * @covers SearchSuggestionSet::getBestScore - * @covers SearchSuggestionSet::prepend - */ - public function testInsertBest() { - $set = SearchSuggestionSet::emptySuggestionSet(); - $this->assertEquals( 0, $set->getSize() ); - $set->prepend( new SearchSuggestion( 3 ) ); - $this->assertEquals( 3, $set->getWorstScore() ); - $this->assertEquals( 3, $set->getBestScore() ); - - $suggestion = new SearchSuggestion( 4 ); - $set->prepend( $suggestion ); - $this->assertEquals( 3, $set->getWorstScore() ); - $this->assertEquals( 4, $set->getBestScore() ); - $this->assertEquals( 4, $suggestion->getScore() ); - - $suggestion = new SearchSuggestion( 0 ); - $set->prepend( $suggestion ); - $this->assertEquals( 3, $set->getWorstScore() ); - $this->assertEquals( 5, $set->getBestScore() ); - $this->assertEquals( 5, $suggestion->getScore() ); - - $suggestion = new SearchSuggestion( 2 ); - $set->prepend( $suggestion ); - $this->assertEquals( 3, $set->getWorstScore() ); - $this->assertEquals( 6, $set->getBestScore() ); - $this->assertEquals( 6, $suggestion->getScore() ); - - $scores = $set->map( function ( $s ) { - return $s->getScore(); - } ); - $sorted = $scores; - asort( $sorted ); - $this->assertEquals( $sorted, $scores ); - } - - /** - * @covers SearchSuggestionSet::shrink - */ - public function testShrink() { - $set = SearchSuggestionSet::emptySuggestionSet(); - for ( $i = 0; $i < 100; $i++ ) { - $set->append( new SearchSuggestion( 0 ) ); - } - $set->shrink( 10 ); - $this->assertEquals( 10, $set->getSize() ); - - $set->shrink( 0 ); - $this->assertEquals( 0, $set->getSize() ); - } - - // TODO: test for fromTitles -} diff --git a/tests/phpunit/includes/shell/CommandFactoryTest.php b/tests/phpunit/includes/shell/CommandFactoryTest.php deleted file mode 100644 index b031431af7..0000000000 --- a/tests/phpunit/includes/shell/CommandFactoryTest.php +++ /dev/null @@ -1,50 +0,0 @@ - 1000, - 'memory' => 1000, - 'time' => 30, - 'walltime' => 40, - ]; - - $factory = new CommandFactory( $limits, $cgroup, false ); - $factory->setLogger( $logger ); - $factory->logStderr(); - $command = $factory->create(); - $this->assertInstanceOf( Command::class, $command ); - - $wrapper = TestingAccessWrapper::newFromObject( $command ); - $this->assertSame( $logger, $wrapper->logger ); - $this->assertSame( $cgroup, $wrapper->cgroup ); - $this->assertSame( $limits, $wrapper->limits ); - $this->assertTrue( $wrapper->doLogStderr ); - } - - /** - * @covers MediaWiki\Shell\CommandFactory::create - */ - public function testFirejailCreate() { - $factory = new CommandFactory( [], false, 'firejail' ); - $factory->setLogger( new NullLogger() ); - $this->assertInstanceOf( FirejailCommand::class, $factory->create() ); - } -} diff --git a/tests/phpunit/includes/site/SiteExporterTest.php b/tests/phpunit/includes/site/SiteExporterTest.php deleted file mode 100644 index 97a43f8d5b..0000000000 --- a/tests/phpunit/includes/site/SiteExporterTest.php +++ /dev/null @@ -1,148 +0,0 @@ -setExpectedException( InvalidArgumentException::class ); - - new SiteExporter( 'Foo' ); - } - - public function testExportSites() { - $foo = Site::newForType( Site::TYPE_UNKNOWN ); - $foo->setGlobalId( 'Foo' ); - - $acme = Site::newForType( Site::TYPE_UNKNOWN ); - $acme->setGlobalId( 'acme.com' ); - $acme->setGroup( 'Test' ); - $acme->addLocalId( Site::ID_INTERWIKI, 'acme' ); - $acme->setPath( Site::PATH_LINK, 'http://acme.com/' ); - - $tmp = tmpfile(); - $exporter = new SiteExporter( $tmp ); - - $exporter->exportSites( [ $foo, $acme ] ); - - fseek( $tmp, 0 ); - $xml = fread( $tmp, 16 * 1024 ); - - $this->assertContains( 'assertContains( '', $xml ); - $this->assertContains( 'Foo', $xml ); - $this->assertContains( '', $xml ); - $this->assertContains( 'acme.com', $xml ); - $this->assertContains( 'Test', $xml ); - $this->assertContains( 'acme', $xml ); - $this->assertContains( 'http://acme.com/', $xml ); - $this->assertContains( '', $xml ); - - // NOTE: HHVM (at least on wmf Jenkins) doesn't like file URLs. - $xsdFile = __DIR__ . '/../../../../docs/sitelist-1.0.xsd'; - $xsdData = file_get_contents( $xsdFile ); - - $document = new DOMDocument(); - $document->loadXML( $xml, LIBXML_NONET ); - $document->schemaValidateSource( $xsdData ); - } - - private function newSiteStore( SiteList $sites ) { - $store = $this->getMockBuilder( SiteStore::class )->getMock(); - - $store->expects( $this->once() ) - ->method( 'saveSites' ) - ->will( $this->returnCallback( function ( $moreSites ) use ( $sites ) { - foreach ( $moreSites as $site ) { - $sites->setSite( $site ); - } - } ) ); - - $store->expects( $this->any() ) - ->method( 'getSites' ) - ->will( $this->returnValue( new SiteList() ) ); - - return $store; - } - - public function provideRoundTrip() { - $foo = Site::newForType( Site::TYPE_UNKNOWN ); - $foo->setGlobalId( 'Foo' ); - - $acme = Site::newForType( Site::TYPE_UNKNOWN ); - $acme->setGlobalId( 'acme.com' ); - $acme->setGroup( 'Test' ); - $acme->addLocalId( Site::ID_INTERWIKI, 'acme' ); - $acme->setPath( Site::PATH_LINK, 'http://acme.com/' ); - - $dewiki = Site::newForType( Site::TYPE_MEDIAWIKI ); - $dewiki->setGlobalId( 'dewiki' ); - $dewiki->setGroup( 'wikipedia' ); - $dewiki->setForward( true ); - $dewiki->addLocalId( Site::ID_INTERWIKI, 'wikipedia' ); - $dewiki->addLocalId( Site::ID_EQUIVALENT, 'de' ); - $dewiki->setPath( Site::PATH_LINK, 'http://de.wikipedia.org/w/' ); - $dewiki->setPath( MediaWikiSite::PATH_PAGE, 'http://de.wikipedia.org/wiki/' ); - $dewiki->setSource( 'meta.wikimedia.org' ); - - return [ - 'empty' => [ - new SiteList() - ], - - 'some' => [ - new SiteList( [ $foo, $acme, $dewiki ] ), - ], - ]; - } - - /** - * @dataProvider provideRoundTrip() - */ - public function testRoundTrip( SiteList $sites ) { - $tmp = tmpfile(); - $exporter = new SiteExporter( $tmp ); - - $exporter->exportSites( $sites ); - - fseek( $tmp, 0 ); - $xml = fread( $tmp, 16 * 1024 ); - - $actualSites = new SiteList(); - $store = $this->newSiteStore( $actualSites ); - - $importer = new SiteImporter( $store ); - $importer->importFromXML( $xml ); - - $this->assertEquals( $sites, $actualSites ); - } - -} diff --git a/tests/phpunit/includes/site/SiteImporterTest.php b/tests/phpunit/includes/site/SiteImporterTest.php deleted file mode 100644 index dbdbd6fcc2..0000000000 --- a/tests/phpunit/includes/site/SiteImporterTest.php +++ /dev/null @@ -1,200 +0,0 @@ -getMockBuilder( SiteStore::class )->getMock(); - - $store->expects( $this->once() ) - ->method( 'saveSites' ) - ->will( $this->returnCallback( function ( $sites ) use ( $expectedSites ) { - $this->assertSitesEqual( $expectedSites, $sites ); - } ) ); - - $store->expects( $this->any() ) - ->method( 'getSites' ) - ->will( $this->returnValue( new SiteList() ) ); - - $errorHandler = $this->getMockBuilder( Psr\Log\LoggerInterface::class )->getMock(); - $errorHandler->expects( $this->exactly( $errorCount ) ) - ->method( 'error' ); - - $importer = new SiteImporter( $store ); - $importer->setExceptionCallback( [ $errorHandler, 'error' ] ); - - return $importer; - } - - public function assertSitesEqual( $expected, $actual, $message = '' ) { - $this->assertEquals( - $this->getSerializedSiteList( $expected ), - $this->getSerializedSiteList( $actual ), - $message - ); - } - - public function provideImportFromXML() { - $foo = Site::newForType( Site::TYPE_UNKNOWN ); - $foo->setGlobalId( 'Foo' ); - - $acme = Site::newForType( Site::TYPE_UNKNOWN ); - $acme->setGlobalId( 'acme.com' ); - $acme->setGroup( 'Test' ); - $acme->addLocalId( Site::ID_INTERWIKI, 'acme' ); - $acme->setPath( Site::PATH_LINK, 'http://acme.com/' ); - - $dewiki = Site::newForType( Site::TYPE_MEDIAWIKI ); - $dewiki->setGlobalId( 'dewiki' ); - $dewiki->setGroup( 'wikipedia' ); - $dewiki->setForward( true ); - $dewiki->addLocalId( Site::ID_INTERWIKI, 'wikipedia' ); - $dewiki->addLocalId( Site::ID_EQUIVALENT, 'de' ); - $dewiki->setPath( Site::PATH_LINK, 'http://de.wikipedia.org/w/' ); - $dewiki->setPath( MediaWikiSite::PATH_PAGE, 'http://de.wikipedia.org/wiki/' ); - $dewiki->setSource( 'meta.wikimedia.org' ); - - return [ - 'empty' => [ - '', - [], - ], - 'no sites' => [ - 'FooBla', - [], - ], - 'minimal' => [ - '' . - 'Foo' . - '', - [ $foo ], - ], - 'full' => [ - '' . - 'Foo' . - '' . - 'acme.com' . - 'acme' . - 'Test' . - 'http://acme.com/' . - '' . - '' . - 'meta.wikimedia.org' . - 'dewiki' . - 'wikipedia' . - 'de' . - 'wikipedia' . - '' . - 'http://de.wikipedia.org/w/' . - 'http://de.wikipedia.org/wiki/' . - '' . - '', - [ $foo, $acme, $dewiki ], - ], - 'skip' => [ - '' . - 'Foo' . - 'Foo' . - '' . - 'acme.com' . - 'acme' . - 'boop!' . - 'Test' . - 'http://acme.com/' . - '' . - '', - [ $foo, $acme ], - 1 - ], - ]; - } - - /** - * @dataProvider provideImportFromXML - */ - public function testImportFromXML( $xml, array $expectedSites, $errorCount = 0 ) { - $importer = $this->newSiteImporter( $expectedSites, $errorCount ); - $importer->importFromXML( $xml ); - } - - public function testImportFromXML_malformed() { - $this->setExpectedException( Exception::class ); - - $store = $this->getMockBuilder( SiteStore::class )->getMock(); - $importer = new SiteImporter( $store ); - $importer->importFromXML( 'THIS IS NOT XML' ); - } - - public function testImportFromFile() { - $foo = Site::newForType( Site::TYPE_UNKNOWN ); - $foo->setGlobalId( 'Foo' ); - - $acme = Site::newForType( Site::TYPE_UNKNOWN ); - $acme->setGlobalId( 'acme.com' ); - $acme->setGroup( 'Test' ); - $acme->addLocalId( Site::ID_INTERWIKI, 'acme' ); - $acme->setPath( Site::PATH_LINK, 'http://acme.com/' ); - - $dewiki = Site::newForType( Site::TYPE_MEDIAWIKI ); - $dewiki->setGlobalId( 'dewiki' ); - $dewiki->setGroup( 'wikipedia' ); - $dewiki->setForward( true ); - $dewiki->addLocalId( Site::ID_INTERWIKI, 'wikipedia' ); - $dewiki->addLocalId( Site::ID_EQUIVALENT, 'de' ); - $dewiki->setPath( Site::PATH_LINK, 'http://de.wikipedia.org/w/' ); - $dewiki->setPath( MediaWikiSite::PATH_PAGE, 'http://de.wikipedia.org/wiki/' ); - $dewiki->setSource( 'meta.wikimedia.org' ); - - $importer = $this->newSiteImporter( [ $foo, $acme, $dewiki ], 0 ); - - $file = __DIR__ . '/SiteImporterTest.xml'; - $importer->importFromFile( $file ); - } - - /** - * @param Site[] $sites - * - * @return array[] - */ - private function getSerializedSiteList( $sites ) { - $serialized = []; - - foreach ( $sites as $site ) { - $key = $site->getGlobalId(); - $data = unserialize( $site->serialize() ); - - $serialized[$key] = $data; - } - - return $serialized; - } -} diff --git a/tests/phpunit/includes/site/SiteImporterTest.xml b/tests/phpunit/includes/site/SiteImporterTest.xml deleted file mode 100644 index 720b1faf1a..0000000000 --- a/tests/phpunit/includes/site/SiteImporterTest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - Foo - - acme.com - acme - Test - http://acme.com/ - - - meta.wikimedia.org - dewiki - wikipedia - de - wikipedia - - http://de.wikipedia.org/w/ - http://de.wikipedia.org/wiki/ - - diff --git a/tests/phpunit/includes/tidy/RemexDriverTest.php b/tests/phpunit/includes/tidy/RemexDriverTest.php deleted file mode 100644 index 5ad8416b81..0000000000 --- a/tests/phpunit/includes/tidy/RemexDriverTest.php +++ /dev/null @@ -1,326 +0,0 @@ -x

" - ], - [ - 'No p-wrap of blank node', - " ", - " " - ], - [ - 'p-wrap terminated by div', - "x
", - "

x

" - ], - [ - 'p-wrap not terminated by span', - "x", - "

x

" - ], - [ - 'An element is non-blank and so gets p-wrapped', - "", - "

" - ], - [ - 'The blank flag is set after a block-level element', - "
", - "
" - ], - [ - 'Blank detection between two block-level elements', - "
", - "
" - ], - [ - 'But p-wrapping of non-blank content works after an element', - "
x", - "

x

" - ], - [ - 'p-wrapping between two block-level elements', - "
x
", - "

x

" - ], - [ - 'p-wrap inside blockquote', - "
x
", - "

x

" - ], - [ - 'A comment is blank for p-wrapping purposes', - "", - "" - ], - [ - 'A comment is blank even when a p-wrap was opened by a text node', - " ", - " " - ], - [ - 'A comment does not open a p-wrap', - "x", - "

x

" - ], - [ - 'A comment does not close a p-wrap', - "x", - "

x

" - ], - [ - 'Empty li', - "", - "" - ], - [ - 'li with element', - "", - "" - ], - [ - 'li with text', - "", - "" - ], - [ - 'Empty tr', - "
", - "
" - ], - [ - 'Empty p', - "

\n

", - "

\n

" - ], - [ - 'No p-wrapping of an inline element which contains a block element (T150317)', - "
x
", - "
x
" - ], - [ - 'p-wrapping of an inline element which contains an inline element', - "x", - "

x

" - ], - [ - 'p-wrapping is enabled in a blockquote in an inline element', - "
x
", - "

x

" - ], - [ - 'All bare text should be p-wrapped even when surrounded by block tags', - "
x
y
z", - "

x

y

z

" - ], - [ - 'Split tag stack 1', - "x
y
z
", - "

x

y

z

" - ], - [ - 'Split tag stack 2', - "
y
z
", - "
y

z

" - ], - [ - 'Split tag stack 3', - "x
y
", - "

x

y
" - ], - [ - 'Split tag stack 4 (modified to use splittable tag)', - "abc
d
e
", - "

abc

d

e

" - ], - [ - "Split tag stack regression check 1", - "x
y
", - "

x

y
" - ], - [ - "Split tag stack regression check 2 (modified to use splittable tag)", - "a
d
e
", - "

a

d

e

" - ], - // Simple tests from pwrap.js - [ - 'Simple pwrap test 1', - 'a', - '

a

' - ], - [ - ' is not a splittable tag, but gets p-wrapped in simple wrapping scenarios', - 'a', - '

a

' - ], - [ - 'Simple pwrap test 3', - 'x
a
b
y', - '

x

a
b

y

' - ], - [ - 'Simple pwrap test 4', - 'x
a
b
y', - '

x

a
b

y

' - ], - // Complex tests from pwrap.js - [ - 'Complex pwrap test 1', - 'x
a
y
', - '

x

a

y

' - ], - [ - 'Complex pwrap test 2', - 'abc
d
e
f', - '

abc

d

ef

' - ], - [ - 'Complex pwrap test 3', - 'abc
d
e
', - '

abc

d

e

' - ], - [ - 'Complex pwrap test 4', - 'x
y
', - '

x

y
' - ], - [ - 'Complex pwrap test 5', - 'a
d
e
', - '

a

d

e

' - ], - // phpcs:disable Generic.Files.LineLength - [ - 'Complex pwrap test 6', - 'a
b
cd
e
f
g
', - // PHP 5 does not allow concatenation in initialisation of a class static variable - '

a

b

cd

e

fg

' - ], - // phpcs:enable - /* FIXME the second causes a stack split which clones the even - * though no

is actually generated - [ - 'Complex pwrap test 7', - '

x
y
z
', - '
x
y
z
' - ], - */ - // New local tests - [ - 'Blank text node after block end', - 'x
y
z
', - '

x

y

z

' - ], - [ - 'Text node fostering (FIXME: wrap missing)', - 'x
', - 'x
' - ], - [ - 'Blockquote fostering', - '
x
', - '

x

' - ], - [ - 'Block element fostering', - '
x', - '
x
' - ], - [ - 'Formatting element fostering (FIXME: wrap missing)', - 'x', - 'x
' - ], - [ - 'AAA clone of p-wrapped element (FIXME: empty b)', - 'x

yz

', - '

x

yz

', - ], - [ - 'AAA with fostering (FIXME: wrap missing)', - '1

23

', - '1

23

' - ], - [ - 'AAA causes reparent of p-wrapped text node (T178632)', - '
x
', - '

x

', - ], - [ - 'p-wrap ended by reparenting (T200827)', - '

', - '

', - ], - [ - 'style tag isn\'t p-wrapped (T186965)', - '', - '', - ], - [ - 'link tag isn\'t p-wrapped (T186965)', - '', - '', - ], - [ - 'style tag doesn\'t split p-wrapping (T208901)', - 'foo bar', - '

foo bar

', - ], - [ - 'link tag doesn\'t split p-wrapping (T208901)', - 'foo bar', - '

foo bar

', - ], - ]; - - public function provider() { - return self::$remexTidyTestData; - } - - /** - * @dataProvider provider - * @covers MediaWiki\Tidy\RemexCompatFormatter - * @covers MediaWiki\Tidy\RemexCompatMunger - * @covers MediaWiki\Tidy\RemexDriver - * @covers MediaWiki\Tidy\RemexMungerData - */ - public function testTidy( $desc, $input, $expected ) { - $r = new MediaWiki\Tidy\RemexDriver( [] ); - $result = $r->tidy( $input ); - $this->assertEquals( $expected, $result, $desc ); - } - - public function html5libProvider() { - $files = json_decode( file_get_contents( __DIR__ . '/html5lib-tests.json' ), true ); - $tests = []; - foreach ( $files as $file => $fileTests ) { - foreach ( $fileTests as $i => $test ) { - $tests[] = [ "$file:$i", $test['data'] ]; - } - } - return $tests; - } - - /** - * This is a quick and dirty test to make sure none of the html5lib tests - * generate exceptions. We don't really know what the expected output is. - * - * @dataProvider html5libProvider - * @coversNothing - */ - public function testHtml5Lib( $desc, $input ) { - $r = new MediaWiki\Tidy\RemexDriver( [] ); - $result = $r->tidy( $input ); - $this->assertTrue( true, $desc ); - } -} diff --git a/tests/phpunit/includes/tidy/html5lib-tests.json b/tests/phpunit/includes/tidy/html5lib-tests.json deleted file mode 100644 index 2b1c3e8cdf..0000000000 --- a/tests/phpunit/includes/tidy/html5lib-tests.json +++ /dev/null @@ -1,80692 +0,0 @@ -{ - "adoption01.dat": [ - { - "data": "

", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,10): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "p": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a" - }, - { - "tag": "p", - "children": [ - { - "tag": "a" - } - ] - } - ] - } - ] - } - ], - "html": "

", - "noQuirksBodyHtml": "

" - } - }, - { - "data": "1

23

", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,12): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "p": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - } - ] - }, - { - "tag": "p", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "2" - } - ] - }, - { - "text": "3" - } - ] - } - ] - } - ] - } - ], - "html": "1

23

", - "noQuirksBodyHtml": "1

23

" - } - }, - { - "data": "1", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,17): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "button": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - } - ] - }, - { - "tag": "button", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "2" - } - ] - }, - { - "text": "3" - } - ] - } - ] - } - ] - } - ], - "html": "1", - "noQuirksBodyHtml": "1" - } - }, - { - "data": "123", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,12): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "b": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - }, - { - "tag": "b", - "children": [ - { - "text": "2" - } - ] - } - ] - }, - { - "tag": "b", - "children": [ - { - "text": "3" - } - ] - } - ] - } - ] - } - ], - "html": "123", - "noQuirksBodyHtml": "123" - } - }, - { - "data": "1
2
34
5
", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,20): adoption-agency-1.3", - "(1,20): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "div": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - } - ] - }, - { - "tag": "div", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "2" - } - ] - }, - { - "tag": "div", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "3" - } - ] - }, - { - "text": "4" - } - ] - }, - { - "text": "5" - } - ] - } - ] - } - ] - } - ], - "html": "1
2
34
5
", - "noQuirksBodyHtml": "1
2
34
5
" - } - }, - { - "data": "1

23

", - "errors": [ - "(1,7): expected-doctype-but-got-start-tag", - "(1,10): unexpected-start-tag-implies-table-voodoo", - "(1,11): unexpected-character-implies-table-voodoo", - "(1,14): unexpected-start-tag-implies-table-voodoo", - "(1,15): unexpected-character-implies-table-voodoo", - "(1,19): unexpected-end-tag-implies-table-voodoo", - "(1,19): adoption-agency-1.3", - "(1,20): unexpected-character-implies-table-voodoo", - "(1,24): unexpected-end-tag-implies-table-voodoo", - "(1,24): eof-in-table" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "p": true, - "table": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - } - ] - }, - { - "tag": "p", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "2" - } - ] - }, - { - "text": "3" - } - ] - }, - { - "tag": "table" - } - ] - } - ] - } - ], - "html": "1

23

", - "noQuirksBodyHtml": "1

23

" - } - }, - { - "data": "

", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,16): adoption-agency-1.3", - "(1,16): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "b": true, - "a": true, - "p": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "a" - }, - { - "tag": "p", - "children": [ - { - "tag": "a" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "

", - "noQuirksBodyHtml": "

" - } - }, - { - "data": "

", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,16): adoption-agency-1.3", - "(1,16): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "b": true, - "a": true, - "p": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "b" - } - ] - }, - { - "tag": "b", - "children": [ - { - "tag": "p", - "children": [ - { - "tag": "a" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "

", - "noQuirksBodyHtml": "

" - } - }, - { - "data": "

", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,16): adoption-agency-1.3", - "(1,16): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "b": true, - "p": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b" - } - ] - } - ] - }, - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "p", - "children": [ - { - "tag": "a" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "

", - "noQuirksBodyHtml": "

" - } - }, - { - "data": "

123

45", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,30): unexpected-end-tag", - "(1,35): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "p": true, - "s": true, - "b": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "p", - "children": [ - { - "text": "1" - }, - { - "tag": "s", - "attrs": [ - { - "name": "id", - "value": "A" - } - ], - "children": [ - { - "text": "2" - }, - { - "tag": "b", - "attrs": [ - { - "name": "id", - "value": "B" - } - ], - "children": [ - { - "text": "3" - } - ] - } - ] - } - ] - }, - { - "tag": "s", - "attrs": [ - { - "name": "id", - "value": "A" - } - ], - "children": [ - { - "tag": "b", - "attrs": [ - { - "name": "id", - "value": "B" - } - ], - "children": [ - { - "text": "4" - } - ] - } - ] - }, - { - "tag": "b", - "attrs": [ - { - "name": "id", - "value": "B" - } - ], - "children": [ - { - "text": "5" - } - ] - } - ] - } - ] - } - ], - "html": "

123

45", - "noQuirksBodyHtml": "

123

45" - } - }, - { - "data": "13
2
", - "errors": [ - "(1,7): expected-doctype-but-got-start-tag", - "(1,10): unexpected-start-tag-implies-table-voodoo", - "(1,11): unexpected-character-implies-table-voodoo", - "(1,15): unexpected-cell-in-table-body", - "(1,30): unexpected-implied-end-tag-in-table-view" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "table": true, - "tbody": true, - "tr": true, - "td": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "text": "1" - } - ] - }, - { - "tag": "a", - "children": [ - { - "text": "3" - } - ] - }, - { - "tag": "table", - "children": [ - { - "tag": "tbody", - "children": [ - { - "tag": "tr", - "children": [ - { - "tag": "td", - "children": [ - { - "text": "2" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "13
2
", - "noQuirksBodyHtml": "13
2
" - } - }, - { - "data": "AC
B
", - "errors": [ - "(1,7): expected-doctype-but-got-start-tag", - "(1,8): unexpected-character-implies-table-voodoo", - "(1,12): unexpected-cell-in-table-body", - "(1,22): unexpected-character-implies-table-voodoo" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "table": true, - "tbody": true, - "tr": true, - "td": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "text": "AC" - }, - { - "tag": "table", - "children": [ - { - "tag": "tbody", - "children": [ - { - "tag": "tr", - "children": [ - { - "tag": "td", - "children": [ - { - "text": "B" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "AC
B
", - "noQuirksBodyHtml": "AC
B
" - } - }, - { - "data": "
", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,23): unexpected-end-tag", - "(1,23): adoption-agency-1.3" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "a": true, - "svg svg": true, - "svg tr": true, - "svg input": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "svg", - "ns": "http://www.w3.org/2000/svg", - "children": [ - { - "tag": "tr", - "ns": "http://www.w3.org/2000/svg", - "children": [ - { - "tag": "input", - "ns": "http://www.w3.org/2000/svg" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "
", - "noQuirksBodyHtml": "
" - } - }, - { - "data": "
", - "errors": [ - "(1,5): expected-doctype-but-got-start-tag", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): adoption-agency-1.3", - "(1,65): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "div": true, - "a": true, - "b": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "div", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "b" - } - ] - }, - { - "tag": "b", - "children": [ - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a" - }, - { - "tag": "div", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "div", - "children": [ - { - "tag": "div" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "
", - "noQuirksBodyHtml": "
" - } - }, - { - "data": "
", - "errors": [ - "(1,5): expected-doctype-but-got-start-tag", - "(1,32): adoption-agency-1.3", - "(1,32): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "div": true, - "a": true, - "b": true, - "u": true, - "i": true, - "code": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "div", - "children": [ - { - "tag": "a", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "u", - "children": [ - { - "tag": "i", - "children": [ - { - "tag": "code" - } - ] - } - ] - } - ] - } - ] - }, - { - "tag": "u", - "children": [ - { - "tag": "i", - "children": [ - { - "tag": "code", - "children": [ - { - "tag": "div", - "children": [ - { - "tag": "a" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "
", - "noQuirksBodyHtml": "
" - } - }, - { - "data": "xy", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "b": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "text": "x" - } - ] - } - ] - } - ] - } - ] - }, - { - "text": "y" - } - ] - } - ] - } - ], - "html": "xy", - "noQuirksBodyHtml": "xy" - } - }, - { - "data": "

x", - "errors": [ - "(1,3): expected-doctype-but-got-start-tag", - "(1,18): unexpected-end-tag", - "(1,19): expected-closing-tag-but-got-eof" - ], - "document": { - "props": { - "tags": { - "html": true, - "head": true, - "body": true, - "p": true, - "b": true - } - }, - "tree": [ - { - "tag": "html", - "children": [ - { - "tag": "head" - }, - { - "tag": "body", - "children": [ - { - "tag": "p", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b" - } - ] - } - ] - } - ] - } - ] - }, - { - "tag": "p", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "tag": "b", - "children": [ - { - "text": "x" - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ], - "html": "

x

", - "noQuirksBodyHtml": "

x

" - } - }, - { - "data": "