diff options
Diffstat (limited to 'MLEB/Translate/tests/phpunit')
115 files changed, 2448 insertions, 1328 deletions
diff --git a/MLEB/Translate/tests/phpunit/Cache/PersistentDatabaseCacheTest.php b/MLEB/Translate/tests/phpunit/Cache/PersistentDatabaseCacheTest.php new file mode 100644 index 00000000..db2bfce3 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/Cache/PersistentDatabaseCacheTest.php @@ -0,0 +1,339 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\Cache; + +use DateInterval; +use DateTime; +use InvalidArgumentException; +use MediaWiki\Extension\Translate\Utilities\Json\JsonCodec; +use MediaWiki\MediaWikiServices; +use MediaWikiIntegrationTestCase; + +/** + * @covers \MediaWiki\Extension\Translate\Cache\PersistentDatabaseCache + * @covers \MediaWiki\Extension\Translate\Cache\PersistentCacheEntry + */ +class PersistentDatabaseCacheTest extends MediaWikiIntegrationTestCase { + /** @var PersistentDatabaseCache */ + private $persistentCache; + + protected function setUp(): void { + parent::setUp(); + $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); + $jsonCodec = new JsonCodec(); + $this->persistentCache = new PersistentDatabaseCache( $lb, $jsonCodec ); + } + + protected function tearDown(): void { + $this->persistentCache->clear(); + parent::tearDown(); + } + + /** @dataProvider provideTestSet */ + public function testGetSet( + string $keyname, + $value, + ?int $exptime, + ?string $tag + ) { + $entry = new PersistentCacheEntry( + $keyname, + $value, + $exptime, + $tag + ); + + $this->persistentCache->set( $entry ); + + $getEntries = $this->persistentCache->get( $keyname ); + $this->assertCacheEntryEqual( $entry, $getEntries[0] ); + } + + /** @dataProvider provideTestSetMulti */ + public function testGetSetMulti( array $inputs, int $exptime = null, string $tag = null ) { + $entries = $this->getEntriesFromInput( $inputs, $exptime, $tag ); + $this->persistentCache->set( ...$entries ); + + $getEntries = $this->persistentCache->get( ...array_keys( $inputs ) ); + + foreach ( $entries as $index => $entry ) { + $this->assertCacheEntryEqual( + $entry, + $getEntries[$index] + ); + } + } + + public function testHas() { + $entry = new PersistentCacheEntry( 'hello', null, null, null ); + $this->persistentCache->set( $entry ); + $this->assertTrue( $this->persistentCache->has( 'hello' ) ); + $this->assertFalse( $this->persistentCache->has( 'hello2' ) ); + } + + /** @dataProvider provideTestHasEntryWithTag */ + public function testHasEntryWithTag( + array $input, + string $tagToSearch, + bool $expected, + string $message + ) { + $entry = new PersistentCacheEntry( + $input['keyname'], + $input['value'], + $input['exptime'], + $input['tag'] + ); + $this->persistentCache->set( $entry ); + + $hasTag = $this->persistentCache->hasEntryWithTag( $tagToSearch ); + $this->assertSame( $expected, $hasTag, $message ); + } + + /** @dataProvider provideTestHasExpired */ + public function testHasExpiredEntry( array $input, bool $expected ) { + $entry = new PersistentCacheEntry( + $input['keyname'], + $input['value'], + $input['exptime'], + $input['tag'] + ); + + $this->persistentCache->set( $entry ); + + $getEntry = $this->persistentCache->get( $input['keyname'] )[0]; + + $this->assertSame( $expected, $entry->hasExpired() ); + $this->assertSame( $expected, $getEntry->hasExpired() ); + } + + /** @dataProvider provideTestGetByTag */ + public function testGetByTag( + array $inputs, ?int $exptime, ?string $inputTag, string $searchTag, int $count + ) { + $entries = $this->getEntriesFromInput( $inputs, $exptime, $inputTag ); + + $this->persistentCache->set( ...$entries ); + $entries = $this->persistentCache->getByTag( $searchTag ); + + $this->assertCount( $count, $entries ); + } + + public function testDelete() { + $testTag = 'test'; + $entry = new PersistentCacheEntry( 'hello', null, null, $testTag ); + $secondEntry = new PersistentCacheEntry( 'hello2', null, null, $testTag ); + + $this->persistentCache->set( $entry ); + $this->persistentCache->set( $secondEntry ); + + $getEntries = $this->persistentCache->getByTag( $testTag ); + + $this->assertCount( 2, $getEntries ); + + $this->persistentCache->delete( 'hello', 'hello2' ); + + $getEntries = $this->persistentCache->getByTag( $testTag ); + $this->assertEmpty( $getEntries ); + } + + public function testDeleteEntriesWithTag() { + $testTag = 'test'; + $anotherTestTag = 'test2'; + $entry = new PersistentCacheEntry( 'hello', null, null, $testTag ); + $secondEntry = new PersistentCacheEntry( 'hello2', null, null, $testTag ); + $thirdEntry = new PersistentCacheEntry( 'hello2', null, null, $anotherTestTag ); + + $this->persistentCache->set( $entry ); + $this->persistentCache->set( $secondEntry ); + $this->persistentCache->set( $thirdEntry ); + + $this->persistentCache->deleteEntriesWithTag( $testTag ); + + $testTagEntries = $this->persistentCache->getByTag( $testTag ); + $this->assertEmpty( $testTagEntries ); + + $anotherTagEntries = $this->persistentCache->getByTag( $anotherTestTag ); + $this->assertNotEmpty( $anotherTagEntries ); + } + + public function testKeyLength() { + $longTestKey = str_repeat( 'verylongkey', 30 ); + + $this->expectException( InvalidArgumentException::class ); + $this->expectExceptionMessageMatches( '/the length of key/i' ); + + new PersistentCacheEntry( $longTestKey, null, null ); + } + + public function testTagLength() { + $longTestTag = str_repeat( 'verylongtag', 30 ); + + $this->expectException( InvalidArgumentException::class ); + $this->expectExceptionMessageMatches( '/the length of tag/i' ); + + new PersistentCacheEntry( 'testkey', null, null, $longTestTag ); + } + + public function provideTestSet() { + yield [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => ( new DateTime() )->getTimestamp(), + 'tag' => null + ]; + + yield [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => null, + 'tag' => 'test' + ]; + + yield [ + 'keyname' => 'key', + 'value' => null, + 'exptime' => null, + 'tag' => null + ]; + } + + public function provideTestSetMulti() { + yield [ + 'inputs' => [ + 'key' => 'value', + 'key2' => 'value2' + ], + 'exptime' => null, + 'tag' => null + ]; + + yield [ + 'inputs' => [ + 'key5' => 'value5', + 'key6' => null + ], + 'exptime' => ( new DateTime() )->getTimestamp(), + 'tag' => 'test' + ]; + } + + public function provideTestHasEntryWithTag() { + $testTag = 'test'; + $today = new DateTime(); + $tomorrow = ( new DateTime() )->add( new DateInterval( 'P1D' ) ); + $yesterday = ( new DateTime() )->sub( new DateInterval( 'P1D' ) ); + + yield [ + 'input' => [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => $today->getTimestamp(), + 'tag' => null + ], + 'expectedTag' => $testTag, + 'hasEntryWithTag' => false, + 'testMessage' => 'return false if no tag is present' + ]; + + yield [ + 'input' => [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => $tomorrow->getTimestamp(), + 'tag' => $testTag + ], + 'expectedTag' => $testTag, + 'hasEntryWithTag' => true, + 'testMessage' => 'return true if tag is present' + ]; + + yield [ + 'input' => [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => $yesterday->getTimestamp(), + 'tag' => $testTag + ], + 'expectedTag' => $testTag, + 'hasEntryWithTag' => true, + 'testMessage' => 'return true for entries that have expired' + ]; + } + + public function provideTestHasExpired() { + $tomorrow = ( new DateTime() )->add( new DateInterval( 'P1D' ) ); + $yesterday = ( new DateTime() )->sub( new DateInterval( 'P1D' ) ); + + yield [ + 'input' => [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => $tomorrow->getTimestamp(), + 'tag' => null + ], + 'hasEntryExpired' => false, + ]; + + yield [ + 'input' => [ + 'keyname' => 'hello', + 'value' => 'World', + 'exptime' => $yesterday->getTimestamp(), + 'tag' => null + ], + 'hasEntryExpired' => true, + ]; + } + + public function provideTestGetByTag() { + $testTag = 'test'; + yield [ + 'inputs' => [ + 'key' => 'value', + 'key2' => 'value2' + ], + 'exptime' => null, + 'tag' => $testTag, + 'test2', + 'expectedEntryCount' => 0 + ]; + + yield [ + 'input' => [ + 'key5' => 'value5', + 'key6' => null + ], + 'exptime' => ( new DateTime() )->getTimestamp(), + 'tag' => $testTag, + 'expectedTag' => $testTag, + 'expectedEntryCount' => 2 + ]; + } + + private function assertCacheEntryEqual( + PersistentCacheEntry $expected, + PersistentCacheEntry $actual + ): void { + $this->assertSame( $expected->key(), $actual->key() ); + $this->assertEquals( $expected->value(), $actual->value() ); + $this->assertSame( $expected->exptime(), $actual->exptime() ); + $this->assertSame( $expected->tag(), $actual->tag() ); + } + + /** @return PersistentCacheEntry[] */ + private function getEntriesFromInput( array $inputs, ?int $exptime, ?string $tag ): array { + $entries = []; + foreach ( $inputs as $key => $value ) { + $entries[] = new PersistentCacheEntry( + $key, + $value, + $exptime, + $tag + ); + } + + return $entries; + } +} diff --git a/MLEB/Translate/tests/phpunit/ElasticSearchTTMServerTest.php b/MLEB/Translate/tests/phpunit/ElasticSearchTTMServerTest.php new file mode 100644 index 00000000..6fcf9e2a --- /dev/null +++ b/MLEB/Translate/tests/phpunit/ElasticSearchTTMServerTest.php @@ -0,0 +1,37 @@ +<?php +declare( strict_types = 1 ); + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \ElasticSearchTTMServer + */ +class ElasticSearchTTMServerTest extends MediaWikiIntegrationTestCase { + public function setUp(): void { + parent::setUp(); + + $this->config = [ + 'primary' => [ + 'class' => ElasticSearchTTMServer::class, + 'mirrors' => [ 'secondary' ], + ], + 'secondary' => [ + 'class' => ElasticSearchTTMServer::class, + 'mirrors' => [ 'primary', 'unknown' ], + ], + ]; + + $this->setMwGlobals( [ + 'wgTranslateTranslationServices' => $this->config, + 'wgTranslateTranslationDefaultService' => 'primary', + ] ); + } + + public function testMirrorsConfig() { + $primary = TTMServer::factory( $this->config['primary'] ); + $this->assertEquals( [ 'secondary' ], $primary->getMirrors() ); + $secondary = TTMServer::factory( $this->config['secondary'] ); + $this->expectException( TTMServerException::class ); + $secondary->getMirrors(); + } +} diff --git a/MLEB/Translate/tests/phpunit/BlackListTest.php b/MLEB/Translate/tests/phpunit/ExclusionInclusionListTest.php index 833b8f8e..8d3c700c 100644 --- a/MLEB/Translate/tests/phpunit/BlackListTest.php +++ b/MLEB/Translate/tests/phpunit/ExclusionInclusionListTest.php @@ -6,14 +6,9 @@ * @license GPL-2.0-or-later */ -/** - * Unit tests for blacklisting/whitelisting languages for a message group - */ -class BlackListTest extends MediaWikiTestCase { +class ExclusionInclusionListTest extends MediaWikiTestCase { - /** - * @var MessageGroup - */ + /** @var MessageGroup */ protected $group; protected $codes; protected $groupConfiguration = [ @@ -29,13 +24,13 @@ class BlackListTest extends MediaWikiTestCase { ], ]; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->group = MessageGroupBase::factory( $this->groupConfiguration ); $this->codes = array_flip( array_keys( TranslateUtils::getLanguageNames( 'en' ) ) ); } - protected function tearDown() : void { + protected function tearDown(): void { unset( $this->group ); parent::tearDown(); } @@ -45,7 +40,7 @@ class BlackListTest extends MediaWikiTestCase { $this->assertNull( $translatableLanguages ); } - public function testAllBlackList() { + public function testAllExclusionList() { $conf = $this->groupConfiguration; $conf['LANGUAGES'] = [ 'blacklist' => '*', @@ -55,7 +50,7 @@ class BlackListTest extends MediaWikiTestCase { $this->assertEquals( count( $translatableLanguages ), 0 ); } - public function testAllWhiteList() { + public function testAllInclusionList() { $conf = $this->groupConfiguration; $conf['LANGUAGES'] = [ 'whitelist' => '*', @@ -65,7 +60,7 @@ class BlackListTest extends MediaWikiTestCase { $this->assertNull( $translatableLanguages ); } - public function testWhiteListOverrideBlackList() { + public function testInclusionListOverridesExclusionList() { $conf = $this->groupConfiguration; $conf['LANGUAGES'] = [ 'whitelist' => [ 'en', 'hi', 'ta' ], @@ -77,7 +72,7 @@ class BlackListTest extends MediaWikiTestCase { $this->assertTrue( isset( $translatableLanguages['hi'] ) ); } - public function testSomeBlackList() { + public function testSomeExclusionList() { $conf = $this->groupConfiguration; $conf['LANGUAGES'] = [ 'blacklist' => [ 'or', 'hi' ], diff --git a/MLEB/Translate/tests/phpunit/FakeTTMServerTest.php b/MLEB/Translate/tests/phpunit/FakeTTMServerTest.php new file mode 100644 index 00000000..811fb6ad --- /dev/null +++ b/MLEB/Translate/tests/phpunit/FakeTTMServerTest.php @@ -0,0 +1,26 @@ +<?php +declare( strict_types = 1 ); + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \FakeTTMServer + */ +class FakeTTMServerTest extends MediaWikiIntegrationTestCase { + public function testFakeTTMServer() { + $server = new FakeTTMServer(); + $this->assertEquals( + [], + $server->query( 'en', 'fi', 'daa' ), + 'FakeTTMServer returns no suggestions for all queries' + ); + + $title = $this->createMock( Title::class ); + $handle = new MessageHandle( $title ); + + $this->assertNull( + $server->update( $handle, 'text' ), + 'FakeTTMServer update is no-op and always succeeds' + ); + } +} diff --git a/MLEB/Translate/tests/phpunit/HookDocTest.php b/MLEB/Translate/tests/phpunit/HookDocTest.php index 94ee8af4..a23a75e9 100644 --- a/MLEB/Translate/tests/phpunit/HookDocTest.php +++ b/MLEB/Translate/tests/phpunit/HookDocTest.php @@ -29,7 +29,7 @@ class HookDocTest extends MediaWikiIntegrationTestCase { ], ]; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $contents = file_get_contents( __DIR__ . '/../../hooks.txt' ); $blocks = preg_split( '/\n\n/', $contents ); diff --git a/MLEB/Translate/tests/phpunit/Makefile b/MLEB/Translate/tests/phpunit/Makefile index 10dc5a05..1df7c943 100644 --- a/MLEB/Translate/tests/phpunit/Makefile +++ b/MLEB/Translate/tests/phpunit/Makefile @@ -2,7 +2,7 @@ ifndef MW_INSTALL_PATH MW_INSTALL_PATH=../../../.. endif -DIRS = api ffs insertables messagegroups pagetranslation tag translationaids unit utils MessageValidator +DIRS = api ffs messagegroups PageTranslation tag translationaids unit utils Validation default: php ${MW_INSTALL_PATH}/tests/phpunit/phpunit.php . diff --git a/MLEB/Translate/tests/phpunit/MessageCollectionTest.php b/MLEB/Translate/tests/phpunit/MessageCollectionTest.php index 0e8bdec4..9c201241 100644 --- a/MLEB/Translate/tests/phpunit/MessageCollectionTest.php +++ b/MLEB/Translate/tests/phpunit/MessageCollectionTest.php @@ -11,7 +11,7 @@ * @covers MessageCollection */ class MessageCollectionTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -84,9 +84,7 @@ class MessageCollectionTest extends MediaWikiIntegrationTestCase { $this->assertNull( $untranslated->getProperty( 'revision' ) ); } - /** - * @covers MessageCollection::filterChanged - */ + /** @covers MessageCollection::filterChanged */ public function testFilterChanged() { $this->assertTrue( $this->editPage( 'MediaWiki:Changedtranslated_1/fi', 'pupuliini_1' )->isGood() diff --git a/MLEB/Translate/tests/phpunit/MessageGroupBaseTest.php b/MLEB/Translate/tests/phpunit/MessageGroupBaseTest.php index 7353d911..9f47c22d 100644 --- a/MLEB/Translate/tests/phpunit/MessageGroupBaseTest.php +++ b/MLEB/Translate/tests/phpunit/MessageGroupBaseTest.php @@ -1,8 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\Validation\MessageValidator as MessageValidatorInterface; -use MediaWiki\Extensions\Translate\Validation\ValidationIssues; +use MediaWiki\Extension\Translate\TranslatorInterface\Insertable\Insertable; +use MediaWiki\Extension\Translate\TranslatorInterface\Insertable\InsertablesSuggester; +use MediaWiki\Extension\Translate\Validation\MessageValidator; +use MediaWiki\Extension\Translate\Validation\ValidationIssues; +use MediaWiki\Extension\Translate\Validation\ValidationRunner; /** * @license GPL-2.0-or-later @@ -11,7 +14,6 @@ use MediaWiki\Extensions\Translate\Validation\ValidationIssues; class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { /** @var MessageGroup */ protected $group; - protected $groupConfiguration = [ 'BASIC' => [ 'class' => FileBasedMessageGroup::class, @@ -22,12 +24,12 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { ], ]; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->group = MessageGroupBase::factory( $this->groupConfiguration ); } - protected function tearDown() : void { + protected function tearDown(): void { unset( $this->group ); parent::tearDown(); } @@ -88,65 +90,6 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { ); } - public function testInsertablesSuggesterClass() { - $conf = $this->groupConfiguration; - $conf['INSERTABLES']['class'] = FakeInsertablesSuggester::class; - $this->group = MessageGroupBase::factory( $conf ); - - $this->assertArrayEquals( - [ new Insertable( 'Fake', 'Insertables', 'Suggester' ) ], - $this->group->getInsertablesSuggester()->getInsertables( '' ) - ); - } - - public function testInsertablesSuggesterClasses() { - $conf = $this->groupConfiguration; - $conf['INSERTABLES']['classes'] = [ - 'FakeInsertablesSuggester', - 'AnotherFakeInsertablesSuggester', - ]; - $this->group = MessageGroupBase::factory( $conf ); - - $this->assertArrayEquals( - [ - new Insertable( 'Fake', 'Insertables', 'Suggester' ), - new Insertable( 'AnotherFake', 'Insertables', 'Suggester' ), - ], - $this->group->getInsertablesSuggester()->getInsertables( '' ) - ); - } - - public function testInsertablesSuggesterClassAndClasses() { - $conf = $this->groupConfiguration; - $conf['INSERTABLES']['class'] = FakeInsertablesSuggester::class; - $conf['INSERTABLES']['classes'] = [ AnotherFakeInsertablesSuggester::class ]; - $this->group = MessageGroupBase::factory( $conf ); - - $this->assertArrayEquals( - [ - new Insertable( 'Fake', 'Insertables', 'Suggester' ), - new Insertable( 'AnotherFake', 'Insertables', 'Suggester' ), - ], - $this->group->getInsertablesSuggester()->getInsertables( '' ) - ); - - $conf['INSERTABLES']['classes'][] = 'FakeInsertablesSuggester'; - $conf['INSERTABLES']['classes'][] = 'AnotherFakeInsertablesSuggester'; - $this->group = MessageGroupBase::factory( $conf ); - - $this->assertArrayEquals( - [ - new Insertable( 'Fake', 'Insertables', 'Suggester' ), - new Insertable( 'AnotherFake', 'Insertables', 'Suggester' ), - ], - $this->group->getInsertablesSuggester()->getInsertables( '' ), - false, - false, - "should correctly get InsertablesSuggesters using " . - "both 'class' and 'classes' options and removing duplicates." - ); - } - public function testGetNamespaceInvalid() { $conf = $this->groupConfiguration; $conf['BASIC']['namespace'] = 'ergweofijwef'; @@ -185,8 +128,9 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { public function testInsertableValidatorConfiguration() { $conf = $this->groupConfiguration; - unset( $conf['INSERTABLES']['class'] ); - $conf['INSERTABLES']['classes'] = [ AnotherFakeInsertablesSuggester::class ]; + $conf['INSERTABLES'] = [ + [ 'class' => AnotherFakeInsertablesSuggester::class ] + ]; $conf['VALIDATORS'] = []; $conf['VALIDATORS'][] = [ 'class' => FakeInsertableValidator::class, @@ -204,8 +148,8 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { $messageValidators = $this->group->getValidator(); $insertables = $this->group->getInsertablesSuggester()->getInsertables( '' ); - $this->assertInstanceOf( MessageValidator::class, $messageValidators, - "should correctly fetch a 'MessageValidator' using the 'VALIDATOR' configuration." + $this->assertInstanceOf( ValidationRunner::class, $messageValidators, + "should correctly fetch a 'ValidationRunner' using the 'VALIDATOR' configuration." ); // Returns insertables from, @@ -225,8 +169,6 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { public function testInsertableArrayConfiguration() { $conf = $this->groupConfiguration; - unset( $conf['INSERTABLES']['class'] ); - unset( $conf['INSERTABLES']['classes'] ); $conf['INSERTABLES'] = [ [ @@ -257,33 +199,33 @@ class MessageGroupBaseTest extends MediaWikiIntegrationTestCase { } class FakeInsertablesSuggester implements InsertablesSuggester { - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( 'Fake', 'Insertables', 'Suggester' ) ]; } } class AnotherFakeInsertablesSuggester implements InsertablesSuggester { - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( 'AnotherFake', 'Insertables', 'Suggester' ) ]; } } -class FakeInsertableValidator implements MessageValidatorInterface, InsertablesSuggester { +class FakeInsertableValidator implements MessageValidator, InsertablesSuggester { public function getIssues( TMessage $message, string $targetLanguage ): ValidationIssues { return new ValidationIssues(); } - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( 'Fake', 'Insertable', 'Validator' ) ]; } } -class AnotherFakeInsertableValidator implements MessageValidatorInterface, InsertablesSuggester { +class AnotherFakeInsertableValidator implements MessageValidator, InsertablesSuggester { public function getIssues( TMessage $message, string $targetLanguage ): ValidationIssues { return new ValidationIssues(); } - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( 'Another', 'Fake Insertable', 'Validator' ) ]; } } diff --git a/MLEB/Translate/tests/phpunit/MessageGroupStatesUpdaterJobTest.php b/MLEB/Translate/tests/phpunit/MessageGroupStatesUpdaterJobTest.php index 560dfd86..ea90fc16 100644 --- a/MLEB/Translate/tests/phpunit/MessageGroupStatesUpdaterJobTest.php +++ b/MLEB/Translate/tests/phpunit/MessageGroupStatesUpdaterJobTest.php @@ -5,7 +5,7 @@ * @group medium */ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ 'wgTranslateTranslationServices' => [], @@ -34,9 +34,7 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { } } - /** - * @dataProvider provideStatValues - */ + /** @dataProvider provideStatValues */ public function testGetStatValue( $type, $expected ) { $stats = [ MessageGroupStats::TOTAL => 666, @@ -57,9 +55,7 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { ]; } - /** - * @dataProvider provideMatchCondition - */ + /** @dataProvider provideMatchCondition */ public function testMatchCondition( $expected, $value, $condition, $max ) { $actual = MessageGroupStatesUpdaterJob::matchCondition( $value, $condition, $max ); $this->assertEquals( $expected, $actual ); @@ -121,13 +117,13 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { $status = $page->doEditContent( $content, __METHOD__, 0, false, $user ); - self::runJobs(); + self::translateRunJobs(); $currentState = ApiGroupReview::getState( $group, 'fi' ); $this->assertEquals( 'inprogress', $currentState, 'in progress after first translation' ); // First review ApiTranslationReview::doReview( $user, self::getRevisionRecord( $status ), __METHOD__ ); - self::runJobs(); + self::translateRunJobs(); $currentState = ApiGroupReview::getState( $group, 'fi' ); $this->assertEquals( 'inprogress', $currentState, 'in progress while untranslated messages' ); @@ -138,13 +134,13 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { $status = $page->doEditContent( $content, __METHOD__, 0, false, $user ); - self::runJobs(); + self::translateRunJobs(); $currentState = ApiGroupReview::getState( $group, 'fi' ); $this->assertEquals( 'proofreading', $currentState, 'proofreading after second translation' ); // Second review ApiTranslationReview::doReview( $user, self::getRevisionRecord( $status ), __METHOD__ ); - self::runJobs(); + self::translateRunJobs(); $currentState = ApiGroupReview::getState( $group, 'fi' ); $this->assertEquals( 'ready', $currentState, 'ready when all proofread' ); @@ -155,7 +151,7 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { $page->doEditContent( $content, __METHOD__, 0, false, $user ); - self::runJobs(); + self::translateRunJobs(); $currentState = ApiGroupReview::getState( $group, 'fi' ); $this->assertEquals( 'proofreading', @@ -170,7 +166,7 @@ class MessageGroupStatesUpdaterJobTest extends MediaWikiIntegrationTestCase { return $value['revision-record']; } - protected static function runJobs() { + protected static function translateRunJobs() { do { $job = JobQueueGroup::singleton()->pop(); if ( !$job ) { diff --git a/MLEB/Translate/tests/phpunit/MessageGroupsTest.php b/MLEB/Translate/tests/phpunit/MessageGroupsTest.php index adc49e4a..0f5b9d1f 100644 --- a/MLEB/Translate/tests/phpunit/MessageGroupsTest.php +++ b/MLEB/Translate/tests/phpunit/MessageGroupsTest.php @@ -10,7 +10,7 @@ * ^ See AggregateMessageGroup::getGroups -> MessageGroups::getPriority */ class MessageGroupsTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $conf = [ @@ -35,9 +35,7 @@ class MessageGroupsTest extends MediaWikiIntegrationTestCase { MessageIndex::singleton()->rebuild(); } - /** - * @dataProvider provideGroups - */ + /** @dataProvider provideGroups */ public function testGetParentGroups( $expected, $target ) { $group = MessageGroups::getGroup( $target ); $got = MessageGroups::getParentGroups( $group ); diff --git a/MLEB/Translate/tests/phpunit/MessageIndexRebuildJobTest.php b/MLEB/Translate/tests/phpunit/MessageIndexRebuildJobTest.php index 59837677..95c1677d 100644 --- a/MLEB/Translate/tests/phpunit/MessageIndexRebuildJobTest.php +++ b/MLEB/Translate/tests/phpunit/MessageIndexRebuildJobTest.php @@ -10,9 +10,7 @@ * @group medium */ class MessageIndexRebuildJobTest extends MediaWikiIntegrationTestCase { - protected $config = []; - - public function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ diff --git a/MLEB/Translate/tests/phpunit/MessageIndexTest.php b/MLEB/Translate/tests/phpunit/MessageIndexTest.php index f29297b8..5b408ddd 100644 --- a/MLEB/Translate/tests/phpunit/MessageIndexTest.php +++ b/MLEB/Translate/tests/phpunit/MessageIndexTest.php @@ -14,7 +14,7 @@ use Wikimedia\TestingAccessWrapper; * @group large */ class MessageIndexTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ 'wgTranslateCacheDirectory' => $this->getNewTempDirectory(), @@ -48,9 +48,7 @@ class MessageIndexTest extends MediaWikiIntegrationTestCase { yield [ [ 'SerializedMessageIndex' ], SerializedMessageIndex::class ]; } - /** - * @dataProvider provideTranslateMessageIndexConfig - */ + /** @dataProvider provideTranslateMessageIndexConfig */ public function testSingleton( $configValue, $expectedClass ) { $this->setMwGlobals( [ 'wgTranslateMessageIndex' => $configValue, @@ -63,9 +61,7 @@ class MessageIndexTest extends MediaWikiIntegrationTestCase { $this->assertInstanceOf( $expectedClass, $object ); } - /** - * @dataProvider provideTestGetArrayDiff - */ + /** @dataProvider provideTestGetArrayDiff */ public function testGetArrayDiff( $expected, $old, $new ) { $actual = MessageIndex::getArrayDiff( $old, $new ); $this->assertEquals( $expected['keys'], $actual['keys'], 'key diff' ); @@ -165,9 +161,7 @@ class MessageIndexTest extends MediaWikiIntegrationTestCase { return $data; } - /** - * @dataProvider provideMessageIndexImplementation - */ + /** @dataProvider provideMessageIndexImplementation */ public function testMessageIndexImplementation( $mi ) { $data = self::getTestData(); /** @var TestableDatabaseMessageIndex|TestableCDBMessageIndex|TestableSerializedMessageIndex */ @@ -194,7 +188,7 @@ class MessageIndexTest extends MediaWikiIntegrationTestCase { ); } - $this->assertEquals( + $this->assertSame( count( $data ), count( $cached ), 'Cache has same number of elements' diff --git a/MLEB/Translate/tests/phpunit/PageTranslation/TranslationPageTest.php b/MLEB/Translate/tests/phpunit/PageTranslation/TranslationPageTest.php new file mode 100644 index 00000000..706be63b --- /dev/null +++ b/MLEB/Translate/tests/phpunit/PageTranslation/TranslationPageTest.php @@ -0,0 +1,152 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\PageTranslation; + +use FatMessage; +use Language; +use MediaWikiTestCase; +use WikiPageMessageGroup; + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\PageTranslation\TranslationPage + */ +class TranslationPageTest extends MediaWikiTestCase { + /** @dataProvider provideTestGenerateSourceFromTranslations */ + public function testGenerateSourceFromTranslations( + bool $inline, + bool $canWrap, + bool $wrapUntranslated, + array $messages, + string $expected + ) { + // This test skips all the message loading from database + + $template = '<S>'; + $unitMap = []; + foreach ( $messages as $id => $m ) { + /** @var FatMessage $m */ + $unit = new TranslationUnit(); + $unit->id = $id; + $unit->text = $m->definition(); + $unit->setIsInline( $inline ); + $unit->setCanWrap( $canWrap ); + + $unitMap[$unit->id] = $unit; + } + + // Then create appropriate units in the section. We are using the array keys, which + // works as long as there are less than ten units. + $sectionMap = [ '<S>' => new Section( '', implode( ' | ', array_keys( $unitMap ) ), '' ) ]; + $output = new ParserOutput( $template, $sectionMap, $unitMap ); + + $translationPage = new TranslationPage( + $output, + $this->createMock( WikiPageMessageGroup::class ), + Language::factory( 'ar' ), + Language::factory( 'en' ), + true /*$showOutdated*/, + $wrapUntranslated, + '' /*$prefix*/ + ); + + $actual = $translationPage->generateSourceFromTranslations( $messages ); + $this->assertSame( $expected, $actual ); + } + + public function provideTestGenerateSourceFromTranslations() { + $inline = true; + $block = false; + + $wrap = true; + $nowrap = false; + + $wrapUntranslated = true; + + $sectionText = 'Hello'; + + $okMessage = new FatMessage( 'ignoredKey', $sectionText ); + $okMessage->setTranslation( 'Hallo' ); + + $fuzzyMessage = new FatMessage( 'ignoredKey', $sectionText ); + $fuzzyMessage->setTranslation( 'hallo' ); + $fuzzyMessage->addTag( 'fuzzy' ); + + $untranslatedMessage = new FatMessage( 'ignoredKey', $sectionText ); + + $identicalMessage = new FatMessage( 'ignoredKey', $sectionText ); + $identicalMessage->setTranslation( $sectionText ); + + $inlineWrappedOutdated = '<span class="mw-translate-fuzzy">hallo</span>'; + $inlineWrappedUntranslated = '<span lang="en" dir="ltr" class="mw-content-ltr">Hello</span>'; + $blockWrappedOutdated = "<div class=\"mw-translate-fuzzy\">\nhallo\n</div>"; + $blockWrappedUntranslated = "<div lang=\"en\" dir=\"ltr\" class=\"mw-content-ltr\">\nHello\n</div>"; + + // Matrix of (inline|block) * (no)wrap * (no)wrapUntranslated + yield [ + $inline, + $wrap, + $wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + "Hallo | $inlineWrappedOutdated | Hello | $inlineWrappedUntranslated" + ]; + + yield [ + $inline, + $wrap, + !$wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + "Hallo | $inlineWrappedOutdated | Hello | Hello" + ]; + + yield [ + $inline, + $nowrap, + $wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + 'Hallo | hallo | Hello | Hello', + ]; + + yield [ + $inline, + $nowrap, + !$wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + 'Hallo | hallo | Hello | Hello', + ]; + + yield [ + $block, + $wrap, + $wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + "Hallo | $blockWrappedOutdated | Hello | $blockWrappedUntranslated" + ]; + + yield [ + $block, + $wrap, + !$wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + "Hallo | $blockWrappedOutdated | Hello | Hello" + ]; + + yield [ + $block, + $nowrap, + $wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + 'Hallo | hallo | Hello | Hello', + ]; + + yield [ + $block, + $nowrap, + !$wrapUntranslated, + [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], + 'Hallo | hallo | Hello | Hello', + ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/ServicesTest.php b/MLEB/Translate/tests/phpunit/ServicesTest.php index c5cca12e..13676178 100644 --- a/MLEB/Translate/tests/phpunit/ServicesTest.php +++ b/MLEB/Translate/tests/phpunit/ServicesTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\Services; +use MediaWiki\Extension\Translate\Services; /** * @author Niklas Laxström * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\Services + * @covers \MediaWiki\Extension\Translate\Services */ class ServicesTest extends MediaWikiIntegrationTestCase { public function testNoExceptions() { diff --git a/MLEB/Translate/tests/phpunit/StringMatcherTest.php b/MLEB/Translate/tests/phpunit/StringMatcherTest.php index 35b14a0f..fad88506 100644 --- a/MLEB/Translate/tests/phpunit/StringMatcherTest.php +++ b/MLEB/Translate/tests/phpunit/StringMatcherTest.php @@ -7,9 +7,7 @@ */ class StringMatcherTest extends MediaWikiIntegrationTestCase { - /** - * @dataProvider messageKeyProvider - */ + /** @dataProvider messageKeyProvider */ public function testKeyPrefixing( string $key, string $expected, string $prefix, array $rules ): void { @@ -54,9 +52,7 @@ class StringMatcherTest extends MediaWikiIntegrationTestCase { return $keys; } - /** - * @dataProvider problematicMessageKeyProvider - */ + /** @dataProvider problematicMessageKeyProvider */ public function testKeyMangling( string $key ): void { $matcher = new StringMatcher(); $mangled = $matcher->mangle( $key ); @@ -67,9 +63,7 @@ class StringMatcherTest extends MediaWikiIntegrationTestCase { $this->assertEquals( $key, $unmangled, 'Mangling is reversible' ); } - /** - * @dataProvider problematicMessageKeyProvider - */ + /** @dataProvider problematicMessageKeyProvider */ public function testKeyManglingWithPrefixing( string $key ): void { $matcher = new StringMatcher( 'prefix', [ '*' ] ); $mangled = $matcher->mangle( $key ); diff --git a/MLEB/Translate/tests/phpunit/Synchronization/GroupSynchronizationCacheTest.php b/MLEB/Translate/tests/phpunit/Synchronization/GroupSynchronizationCacheTest.php new file mode 100644 index 00000000..c9ccc0a5 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/Synchronization/GroupSynchronizationCacheTest.php @@ -0,0 +1,305 @@ +<?php + +namespace MediaWiki\Extension\Translate\Synchronization; + +use InvalidArgumentException; +use LogicException; +use MediaWiki\Extension\Translate\Cache\PersistentDatabaseCache; +use MediaWiki\Extension\Translate\Services; +use MediaWiki\MediaWikiServices; +use MediaWikiIntegrationTestCase; + +/** + * @covers \MediaWiki\Extension\Translate\Synchronization\GroupSynchronizationCache + * @covers \MediaWiki\Extension\Translate\Synchronization\GroupSynchronizationResponse + */ +class GroupSynchronizationCacheTest extends MediaWikiIntegrationTestCase { + /** @var GroupSynchronizationCache */ + private $groupSyncCache; + + protected function setUp(): void { + parent::setUp(); + $this->groupSyncCache = $this->getGroupSynchronizationCache(); + } + + public function testIsGroupBeingProcessed() { + $groupId = 'hello'; + $this->groupSyncCache->markGroupForSync( $groupId ); + + $this->assertTrue( $this->groupSyncCache->isGroupBeingProcessed( $groupId ) ); + + $this->groupSyncCache->endSync( $groupId ); + + $this->assertFalse( $this->groupSyncCache->isGroupBeingProcessed( $groupId ) ); + } + + public function testGetGroupMessages() { + $groupId = 'hello'; + $title = 'Title'; + + $this->groupSyncCache->markGroupForSync( $groupId ); + $messageParam = $this->getMessageParam( $groupId, $title ); + $this->groupSyncCache->addMessages( $groupId, $messageParam ); + + $this->assertEquals( + [ $title => $messageParam ], + $this->groupSyncCache->getGroupMessages( $groupId ) + ); + + $this->groupSyncCache->removeMessages( $groupId, $title ); + + $this->assertSame( [], $this->groupSyncCache->getGroupMessages( $groupId ) ); + } + + public function testMultiGetGroupMessages() { + $groupId = 'hello'; + + $addedMessages = [ + 'Title' => $this->getMessageParam( $groupId, 'Title' ), + 'Title_ABC' => $this->getMessageParam( $groupId, 'Title_ABC' ) + ]; + + $this->groupSyncCache->addMessages( $groupId, ...array_values( $addedMessages ) ); + + $messages = $this->groupSyncCache->getGroupMessages( $groupId ); + $this->assertEquals( $addedMessages, $messages ); + } + + public function testIsMessageBeingProcessed() { + $groupId = 'hello'; + $title = 'Title'; + + $this->groupSyncCache->addMessages( + $groupId, $this->getMessageParam( $groupId, $title ) + ); + + $this->assertTrue( $this->groupSyncCache->isMessageBeingProcessed( $groupId, $title ) ); + + $this->groupSyncCache->removeMessages( $groupId, $title ); + + $this->assertFalse( $this->groupSyncCache->isMessageBeingProcessed( $groupId, $title ) ); + } + + public function testGetGroupsInSync() { + $groupId = 'hello'; + + $this->groupSyncCache->markGroupForSync( $groupId ); + $this->assertSame( [ $groupId ], $this->groupSyncCache->getGroupsInSync() ); + + $this->groupSyncCache->endSync( $groupId ); + $this->assertSame( [], $this->groupSyncCache->getGroupsInSync() ); + } + + public function testEndSync() { + $groupId = 'group-id'; + $title = 'hello'; + + $this->startGroupSync( $groupId, $title ); + + $this->expectExceptionMessageMatches( '/cannot end synchronization/i' ); + $this->expectException( InvalidArgumentException::class ); + + $this->groupSyncCache->endSync( $groupId ); + + $messages = $this->groupSyncCache->getGroupMessages( $groupId ); + $this->assertNotEmpty( $messages, 'endSync should not remove group messages' ); + $this->assertIsInt( + $this->groupSyncCache->getSyncEndTime( $groupId ), + 'endSync should not remove the group key' + ); + } + + public function testForceEndSync() { + $groupId = 'group-id'; + $title = 'hello'; + + $this->startGroupSync( $groupId, $title ); + + $this->groupSyncCache->forceEndSync( $groupId ); + + $messages = $this->groupSyncCache->getGroupMessages( $groupId ); + $this->assertEmpty( $messages, 'forceEndSync should remove group messages' ); + $this->assertNull( + $this->groupSyncCache->getSyncEndTime( $groupId ), + 'forceEndSync should remove the group key' + ); + } + + /** @dataProvider provideGetSynchronizationStatus */ + public function testGetSynchronizationStatus( + GroupSynchronizationCache $syncCache, + string $groupId, + array $titlesToAdd, + array $titlesToRemove, + bool $hasTimedOut = false + ) { + $syncCache->markGroupForSync( $groupId ); + + $this->assertTrue( $syncCache->isGroupBeingProcessed( $groupId ) ); + + $addedMessages = []; + foreach ( $titlesToAdd as $title ) { + $messageParam = $this->getMessageParam( $groupId, $title ); + $syncCache->addMessages( $groupId, $messageParam ); + $addedMessages[$title] = $messageParam; + } + + $this->assertEqualsCanonicalizing( $addedMessages, $syncCache->getGroupMessages( $groupId ) ); + + $syncCache->removeMessages( $groupId, ...$titlesToRemove ); + + $groupSyncResponse = $syncCache->getSynchronizationStatus( $groupId ); + + $diffTitles = array_values( array_diff( $titlesToAdd, $titlesToRemove ) ); + $diffMessages = []; + foreach ( $diffTitles as $title ) { + $diffMessages[$title] = $addedMessages[$title]; + } + + $this->assertEquals( $diffMessages, $syncCache->getGroupMessages( $groupId ) ); + + if ( $diffMessages === [] ) { + // getSynchronizationStatus does not perform any updates + $this->assertContains( $groupId, $this->groupSyncCache->getGroupsInSync() ); + } + + $this->assertSame( $diffMessages === [], $groupSyncResponse->isDone() ); + $this->assertSame( $hasTimedOut, $groupSyncResponse->hasTimedOut() ); + $this->assertEquals( $diffMessages, $groupSyncResponse->getRemainingMessages() ); + $this->assertSame( $groupId, $groupSyncResponse->getGroupId() ); + } + + public function testAddGroupErrors() { + $this->assertEmpty( $this->groupSyncCache->getGroupsWithErrors() ); + + $groupId = 'test-group'; + $groupSyncResponse = $this->addTestGroupError( $groupId ); + $this->assertContains( $groupId, $this->groupSyncCache->getGroupsWithErrors() ); + $this->assertEquals( $groupSyncResponse, $this->groupSyncCache->getGroupErrorInfo( $groupId ) ); + + $this->groupSyncCache->addGroupErrors( $groupSyncResponse ); + $this->assertContains( + $groupId, + $this->groupSyncCache->getGroupsWithErrors(), + 'Multiple additions of group errors don\'t duplicate entries in cache' + ); + $this->assertEquals( + $groupSyncResponse, + $this->groupSyncCache->getGroupErrorInfo( $groupId ), + 'Multiple additions of group errors don\'t duplicate entries in cache' + ); + } + + public function testMarkGroupAsResolved() { + $groupId = 'test-group'; + $this->addTestGroupError( $groupId ); + + $this->assertContains( $groupId, $this->groupSyncCache->getGroupsWithErrors() ); + $this->groupSyncCache->markGroupAsResolved( $groupId ); + $this->assertNotContains( $groupId, $this->groupSyncCache->getGroupsWithErrors() ); + } + + public function testMarkMessageAsResolved() { + $groupId = 'test-group'; + $groupSyncResponse = $this->addTestGroupError( $groupId ); + + $this->assertContains( $groupId, $this->groupSyncCache->getGroupsWithErrors() ); + + $errorMessages = $groupSyncResponse->getRemainingMessages(); + $pageName = $errorMessages[0]->getPageName(); + $this->groupSyncCache->markMessageAsResolved( $groupId, $pageName ); + + $fixedGroupSyncResponse = $this->groupSyncCache->syncGroupErrors( $groupId ); + $fixedErrorMessages = $fixedGroupSyncResponse->getRemainingMessages(); + + $this->assertEquals( count( $errorMessages ) - 1, count( $fixedErrorMessages ) ); + } + + public function testAddGroupErrorsEmpty() { + $groupId = 'test-group'; + $groupHasTimedOut = true; + $groupSyncResponse = new GroupSynchronizationResponse( $groupId, [], $groupHasTimedOut ); + + $this->expectException( LogicException::class ); + $this->groupSyncCache->addGroupErrors( $groupSyncResponse ); + } + + public function provideGetSynchronizationStatus() { + $groupId = 'hello'; + + yield [ + $this->getGroupSynchronizationCache(), + $groupId, + [ 'Title', 'Title1' ], + [ 'Title' ], + false + ]; + + yield [ + $this->getGroupSynchronizationCache(), + $groupId, + [ 'Hello' ], + [ 'Hello' ], + false + ]; + + yield [ + $this->getGroupSynchronizationCache( -1 ), + $groupId, + [ 'Hello' ], + [ 'Hello' ], + false + ]; + + yield [ + $this->getGroupSynchronizationCache( -1 ), + $groupId, + [ 'Hello', 'Title' ], + [ 'Hello' ], + true + ]; + } + + private function getMessageParam( string $groupId, string $title ): MessageUpdateParameter { + return new MessageUpdateParameter( [ + 'fuzzy' => true, + 'content' => 'Hello', + 'title' => $title, + 'groupId' => $groupId + ] ); + } + + private function getGroupSynchronizationCache( int $timeout = null ): GroupSynchronizationCache { + $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); + $jsonCodec = Services::getInstance()->getJsonCodec(); + $persistentCache = new PersistentDatabaseCache( $lb, $jsonCodec ); + $persistentCache->clear(); + + if ( $timeout ) { + return new GroupSynchronizationCache( $persistentCache, $timeout ); + } else { + return new GroupSynchronizationCache( $persistentCache ); + } + } + + private function startGroupSync( string $groupId, string $title ): void { + $this->groupSyncCache->markGroupForSync( $groupId ); + $this->groupSyncCache->addMessages( $groupId, $this->getMessageParam( $groupId, $title ) ); + } + + private function addTestGroupError( string $groupId ): GroupSynchronizationResponse { + $groupHasTimedOut = true; + $groupSyncResponse = new GroupSynchronizationResponse( + $groupId, + [ + $this->getMessageParam( $groupId, 'title1' ), + $this->getMessageParam( $groupId, 'title2' ), + $this->getMessageParam( $groupId, 'title3' ) + ], + $groupHasTimedOut + ); + + $this->groupSyncCache->addGroupErrors( $groupSyncResponse ); + return $groupSyncResponse; + } +} diff --git a/MLEB/Translate/tests/phpunit/TTMServerMessageUpdateJobTest.php b/MLEB/Translate/tests/phpunit/TTMServerMessageUpdateJobTest.php index e0676dbc..29bff823 100644 --- a/MLEB/Translate/tests/phpunit/TTMServerMessageUpdateJobTest.php +++ b/MLEB/Translate/tests/phpunit/TTMServerMessageUpdateJobTest.php @@ -15,7 +15,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { */ public static $mockups = []; - public function setUp() : void { + protected function setUp(): void { parent::setUp(); self::$mockups = []; $this->setMwGlobals( [ @@ -36,7 +36,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { ] ); } - public function tearDown() : void { + protected function tearDown(): void { parent::tearDown(); self::$mockups = []; } @@ -93,7 +93,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { ->getMock() ); $job->run(); - $this->assertSame( 1, count( $job->getResentJobs() ) ); + $this->assertCount( 1, $job->getResentJobs() ); $expectedParams = [ 'errorCount' => 1, 'service' => 'secondary', @@ -132,7 +132,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { ->getMock() ); $job->run(); - $this->assertEquals( 2, count( $job->getResentJobs() ) ); + $this->assertCount( 2, $job->getResentJobs() ); $expectedParams = [ 'errorCount' => 1, 'service' => 'primary', @@ -249,7 +249,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { ->getMock() ); $job->run(); - $this->assertSame( 1, count( $job->getResentJobs() ) ); + $this->assertCount( 1, $job->getResentJobs() ); $expectedParams = [ 'errorCount' => 0, 'retryCount' => 1, @@ -296,7 +296,7 @@ class TTMServerMessageUpdateJobTest extends MediaWikiIntegrationTestCase { ->getMock() ); $job->run(); - $this->assertEquals( 2, count( $job->getResentJobs() ) ); + $this->assertCount( 2, $job->getResentJobs() ); $expectedParams = [ 'errorCount' => 1, 'retryCount' => 0, diff --git a/MLEB/Translate/tests/phpunit/TTMServerTest.php b/MLEB/Translate/tests/phpunit/TTMServerTest.php deleted file mode 100644 index ac706a24..00000000 --- a/MLEB/Translate/tests/phpunit/TTMServerTest.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * @file - * @author Niklas Laxström - * @copyright Copyright © 2012-2013, Niklas Laxström - * @license GPL-2.0-or-later - */ - -class TTMServerTest extends MediaWikiIntegrationTestCase { - protected $config; - - protected function setUp() : void { - global $wgTranslateTranslationServices; - $this->config = $wgTranslateTranslationServices; - parent::setUp(); - - $wgTranslateTranslationServices = []; - $wgTranslateTranslationServices['localtm'] = [ - 'url' => 'http://example.com/sandwiki/api.php', - 'displayname' => 'example.com', - 'cutoff' => 0.75, - 'type' => 'ttmserver', - ]; - - $wgTranslateTranslationServices['apitm'] = [ - 'url' => 'http://example.com/w/api.php', - 'displayname' => 'example.com', - 'cutoff' => 0.75, - 'timeout-sync' => 4, - 'timeout-async' => 4, - 'type' => 'ttmserver', - 'class' => RemoteTTMServer::class, - ]; - } - - protected function tearDown() : void { - global $wgTranslateTranslationServices; - $wgTranslateTranslationServices = $this->config; - parent::tearDown(); - } - - public function testConstruct() { - $server = TTMServer::primary(); - $this->assertEquals( - 'FakeTTMServer', - get_class( $server ), - 'Fake server given when default server is disabled' - ); - global $wgTranslateTranslationServices, - $wgTranslateTranslationDefaultService; - $wgTranslateTranslationServices[$wgTranslateTranslationDefaultService] = [ - 'database' => false, // Passed to wfGetDB - 'cutoff' => 0.75, - 'type' => 'ttmserver', - 'public' => false, - ]; - $server = TTMServer::primary(); - $this->assertEquals( - 'DatabaseTTMServer', - get_class( $server ), - 'Real server given when default server is enabled' - ); - unset( $wgTranslateTranslationServices[$wgTranslateTranslationDefaultService] ); - } - - public function testFakeTTMServer() { - $server = new FakeTTMServer(); - $this->assertEquals( - [], - $server->query( 'en', 'fi', 'daa' ), - 'FakeTTMServer returns no suggestions for all queries' - ); - - $title = $this->createMock( Title::class ); - $handle = new MessageHandle( $title ); - - $this->assertNull( - $server->update( $handle, 'text' ), - 'FakeTTMServer returns null on update' - ); - } - - public function testMirrorsConfig() { - global $wgTranslateTranslationServices; - $wgTranslateTranslationServices['primary'] = [ - 'class' => ElasticSearchTTMServer::class, - 'mirrors' => [ 'secondary' ] - ]; - $wgTranslateTranslationServices['secondary'] = [ - 'class' => ElasticSearchTTMServer::class, - 'mirrors' => [ 'primary', 'unknown' ] - ]; - $primary = TTMServer::factory( $wgTranslateTranslationServices['primary'] ); - $this->assertEquals( [ 'secondary' ], $primary->getMirrors() ); - $secondary = TTMServer::factory( $wgTranslateTranslationServices['secondary'] ); - $this->expectException( TTMServerException::class ); - $secondary->getMirrors(); - } -} diff --git a/MLEB/Translate/tests/phpunit/TranslateHooksTest.php b/MLEB/Translate/tests/phpunit/TranslateHooksTest.php index 63bcb637..2133d81e 100644 --- a/MLEB/Translate/tests/phpunit/TranslateHooksTest.php +++ b/MLEB/Translate/tests/phpunit/TranslateHooksTest.php @@ -12,7 +12,7 @@ * @group medium */ class TranslateHooksTest extends MediaWikiLangTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -43,7 +43,7 @@ class TranslateHooksTest extends MediaWikiLangTestCase { public function testPreventCategorization() { $user = $this->getTestSysop()->getUser(); - $title = Title::makeTitle( NS_MEDIAWIKI, 'ugakey1/fi' ); + $title = Title::makeTitle( NS_MEDIAWIKI, 'Ugakey1/fi' ); $wikipage = WikiPage::factory( $title ); $content = ContentHandler::makeContent( '[[Category:Shouldnotbe]]', $title ); @@ -54,18 +54,18 @@ class TranslateHooksTest extends MediaWikiLangTestCase { 'translation of known message' ); - $title = Title::makeTitle( NS_MEDIAWIKI, 'ugakey2/qqq' ); + $title = Title::makeTitle( NS_MEDIAWIKI, 'Ugakey2/qqq' ); $wikipage = WikiPage::factory( $title ); $content = ContentHandler::makeContent( '[[Category:Shouldbe]]', $title ); $wikipage->doEditContent( $content, __METHOD__, 0, false, $user ); $this->assertEquals( - [ 'Category:Shouldbe' => 'MediaWiki:ugakey2/qqq' ], + [ 'Category:Shouldbe' => 'MediaWiki:Ugakey2/qqq' ], $title->getParentCategories(), 'message docs' ); - $title = Title::makeTitle( NS_MEDIAWIKI, 'ugakey3/no' ); + $title = Title::makeTitle( NS_MEDIAWIKI, 'Ugakey3/no' ); $wikipage = WikiPage::factory( $title ); $content = ContentHandler::makeContent( '[[Category:Shouldbealso]]', $title ); diff --git a/MLEB/Translate/tests/phpunit/TranslateSandboxTest.php b/MLEB/Translate/tests/phpunit/TranslateSandboxTest.php index 060f42a4..58198f8c 100644 --- a/MLEB/Translate/tests/phpunit/TranslateSandboxTest.php +++ b/MLEB/Translate/tests/phpunit/TranslateSandboxTest.php @@ -9,11 +9,9 @@ use MediaWiki\MediaWikiServices; -/** - * @group Database - */ +/** @group Database */ class TranslateSandboxTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ 'wgTranslateUseSandbox' => true, @@ -24,11 +22,27 @@ class TranslateSandboxTest extends MediaWikiIntegrationTestCase { TranslateHooks::setupTranslate(); } + /** + * @param User $user + * @return array|string[] + */ + private function getUserGroups( User $user ): array { + if ( method_exists( MediaWikiServices::class, 'getUserGroupManager' ) ) { + // MediaWiki 1.35+ + $userGroupManager = MediaWikiServices::getInstance()->getUserGroupManager(); + $groups = $userGroupManager->getUserGroups( $user ); + } else { + $groups = $user->getGroups(); + } + + return $groups; + } + public function testAddUser() { $user = TranslateSandbox::addUser( 'Test user', 'test@blackhole.io', 'test password' ); - $this->assertTrue( $user->isLoggedIn(), 'User exists' ); + $this->assertTrue( $user->isRegistered(), 'User exists' ); - $groups = array_unique( $user->getGroups() ); + $groups = array_unique( $this->getUserGroups( $user ) ); $this->assertSame( [ 'translate-sandboxed' ], $groups, 'User is in the sandboxed group' ); } @@ -36,7 +50,7 @@ class TranslateSandboxTest extends MediaWikiIntegrationTestCase { public function testDeleteUser() { $user = TranslateSandbox::addUser( 'Test user2', 'test@blackhole.io', 'test password' ); TranslateSandbox::deleteUser( $user ); - $this->assertFalse( $user->isLoggedIn(), 'User no longer exists' ); + $this->assertFalse( $user->isRegistered(), 'User no longer exists' ); } public function testDeleteUserPromoted() { @@ -86,7 +100,7 @@ class TranslateSandboxTest extends MediaWikiIntegrationTestCase { $user = TranslateSandbox::addUser( 'Test user6', 'test@blackhole.io', 'test password' ); TranslateSandbox::promoteUser( $user ); - $this->assertContains( 'translator', $user->getGroups() ); + $this->assertContains( 'translator', $this->getUserGroups( $user ) ); } public function testPermissions() { @@ -104,4 +118,12 @@ class TranslateSandboxTest extends MediaWikiIntegrationTestCase { 'Promoted users can edit their own talk page' ); } + + public function testIsSandboxed() { + $userNotInGroup = $this->getTestUser()->getUser(); + $userInGroup = $this->getTestUser( [ 'translate-sandboxed' ] )->getUser(); + + $this->assertTrue( TranslateSandbox::isSandboxed( $userInGroup ) ); + $this->assertFalse( TranslateSandbox::isSandboxed( $userNotInGroup ) ); + } } diff --git a/MLEB/Translate/tests/phpunit/TranslateUtilsTest.php b/MLEB/Translate/tests/phpunit/TranslateUtilsTest.php index a97c778b..2c374932 100644 --- a/MLEB/Translate/tests/phpunit/TranslateUtilsTest.php +++ b/MLEB/Translate/tests/phpunit/TranslateUtilsTest.php @@ -3,7 +3,6 @@ use MediaWiki\Revision\RevisionRecord; /** - * Class TranslateUtilsTest * @group Database * @covers TranslateUtils */ diff --git a/MLEB/Translate/tests/phpunit/TranslateYamlTest.php b/MLEB/Translate/tests/phpunit/TranslateYamlTest.php index f89de9ed..84e37cbe 100644 --- a/MLEB/Translate/tests/phpunit/TranslateYamlTest.php +++ b/MLEB/Translate/tests/phpunit/TranslateYamlTest.php @@ -1,13 +1,13 @@ <?php + /** * Tests for yaml wrapper. * * @author Niklas Laxström * @license GPL-2.0-or-later */ - class TranslateYamlTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ diff --git a/MLEB/Translate/tests/phpunit/TranslationFuzzyUpdaterTest.php b/MLEB/Translate/tests/phpunit/TranslationFuzzyUpdaterTest.php index 8f1649bf..2ce9401b 100644 --- a/MLEB/Translate/tests/phpunit/TranslationFuzzyUpdaterTest.php +++ b/MLEB/Translate/tests/phpunit/TranslationFuzzyUpdaterTest.php @@ -14,7 +14,7 @@ use MediaWiki\Revision\RevisionRecord; * @group medium */ class TranslationFuzzyUpdaterTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -48,9 +48,7 @@ class TranslationFuzzyUpdaterTest extends MediaWikiIntegrationTestCase { $content = ContentHandler::makeContent( '$1 van $2', $title ); $status = $page->doEditContent( $content, __METHOD__ ); $value = $status->getValue(); - /** - * @var RevisionRecord $revisionRecord - */ + /** @var RevisionRecord $revisionRecord */ $revisionRecord = $value['revision-record']; $revisionId = $revisionRecord->getId(); diff --git a/MLEB/Translate/tests/phpunit/TranslationStashStorageTest.php b/MLEB/Translate/tests/phpunit/TranslatorSandbox/TranslationStashStorageTest.php index e7a51fa5..af5a8244 100644 --- a/MLEB/Translate/tests/phpunit/TranslationStashStorageTest.php +++ b/MLEB/Translate/tests/phpunit/TranslatorSandbox/TranslationStashStorageTest.php @@ -1,15 +1,18 @@ <?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\TranslatorSandbox; + +use MediaWikiIntegrationTestCase; +use Title; +use User; + /** - * @file * @author Niklas Laxström * @license GPL-2.0-or-later - */ - -/** * @group Database */ class TranslationStashStorageTest extends MediaWikiIntegrationTestCase { - public function testAdd() { $storage = new TranslationStashStorage( wfGetDB( DB_MASTER ) ); diff --git a/MLEB/Translate/tests/phpunit/MessageValidatorTest.php b/MLEB/Translate/tests/phpunit/Validation/ValidationRunnerTest.php index 25dc8fd9..db2058c1 100644 --- a/MLEB/Translate/tests/phpunit/MessageValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/Validation/ValidationRunnerTest.php @@ -7,13 +7,14 @@ * @license GPL-2.0-or-later */ +use MediaWiki\Extension\Translate\Validation\ValidationRunner; + /** - * @covers \MessageValidator - * @covers \MediaWiki\Extensions\Translate\MessageValidator\ValidationResult - * @group TranslationValidators + * @covers \MediaWiki\Extension\Translate\Validation\ValidationRunner + * @covers \MediaWiki\Extension\Translate\Validation\ValidationResult */ -class MessageValidatorTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { +class ValidationRunnerTest extends MediaWikiIntegrationTestCase { + protected function setUp(): void { parent::setUp(); $this->setTemporaryHook( @@ -30,7 +31,7 @@ class MessageValidatorTest extends MediaWikiIntegrationTestCase { // Run with empty ignore list by default $this->setMwGlobals( 'wgTranslateCheckBlacklist', false ); - MessageValidator::reloadIgnorePatterns(); + ValidationRunner::reloadIgnorePatterns(); } public function getTestGroups( &$list ) { @@ -167,7 +168,7 @@ class MessageValidatorTest extends MediaWikiIntegrationTestCase { public function testIgnoreList() { $this->setMwGlobals( [ - 'wgTranslateCheckBlacklist' => __DIR__ . '/data/check-blacklist.php' + 'wgTranslateCheckBlacklist' => __DIR__ . '/../data/check-blacklist.php' ] ); $group = MessageGroups::getGroup( 'test-group' ); @@ -207,6 +208,13 @@ class MessageValidatorTest extends MediaWikiIntegrationTestCase { $validationResult->getIssues(), 'warnings or errors are filtered as per check-blacklist only for specific language code.' ); + + $validationResult = $msgValidator->validateMessage( $collectionFr['regex-key-test'], 'fr' ); + $this->assertCount( + 0, + $validationResult->getIssues(), + 'warnings or errors are filtered as per check-blacklist for specific message key.' + ); } public function testKeyMatching() { diff --git a/MLEB/Translate/tests/phpunit/MessageValidator/Validators/MediaWikiPluralValidatorTest.php b/MLEB/Translate/tests/phpunit/Validation/Validators/MediaWikiPluralValidatorTest.php index 55e57bbf..e99f7276 100644 --- a/MLEB/Translate/tests/phpunit/MessageValidator/Validators/MediaWikiPluralValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/Validation/Validators/MediaWikiPluralValidatorTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiPluralValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MediaWikiPluralValidator; /** * @author Abijeet Patro * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiPluralValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MediaWikiPluralValidator */ class MediaWikiPluralValidatorTest extends PHPUnit\Framework\TestCase { /** @dataProvider getPluralFormCountProvider */ diff --git a/MLEB/Translate/tests/phpunit/WikiPageMessageGroupTest.php b/MLEB/Translate/tests/phpunit/WikiPageMessageGroupTest.php index 09684543..ad57a29b 100644 --- a/MLEB/Translate/tests/phpunit/WikiPageMessageGroupTest.php +++ b/MLEB/Translate/tests/phpunit/WikiPageMessageGroupTest.php @@ -5,11 +5,11 @@ * @file */ - /** - * @group medium - */ +use MediaWiki\Extension\Translate\Validation\ValidationRunner; + +/** @group medium */ class WikiPageMessageGroupTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setTemporaryHook( @@ -36,7 +36,7 @@ class WikiPageMessageGroupTest extends MediaWikiIntegrationTestCase { $group = MessageGroups::getGroup( 'anotherpageid' ); $msgValidator = $group->getValidator(); - $this->assertInstanceOf( MessageValidator::class, $msgValidator, - 'returns a valid object of MessageValidator class.' ); + $this->assertInstanceOf( ValidationRunner::class, $msgValidator, + 'returns a valid object of ValidationRunner class.' ); } } diff --git a/MLEB/Translate/tests/phpunit/api/ApiGroupReviewTest.php b/MLEB/Translate/tests/phpunit/api/ApiGroupReviewTest.php index 3eb9c721..fec499fc 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiGroupReviewTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiGroupReviewTest.php @@ -7,11 +7,9 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\SystemUsers\FuzzyBot; +use MediaWiki\Extension\Translate\SystemUsers\FuzzyBot; -/** - * @group Database - */ +/** @group Database */ class ApiGroupReviewTest extends MediaWikiIntegrationTestCase { public function testGetSetState() { $group = new WikiMessageGroup( 'testgroup', 'wewgweg' ); diff --git a/MLEB/Translate/tests/phpunit/api/ApiManageMessageGroupsTest.php b/MLEB/Translate/tests/phpunit/api/ApiManageMessageGroupsTest.php index 9f3af08b..fcbf6414 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiManageMessageGroupsTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiManageMessageGroupsTest.php @@ -4,22 +4,20 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\MessageSync\MessageSourceChange; +use MediaWiki\Extension\Translate\MessageSync\MessageSourceChange; /** * @group medium * @covers ApiManageMessageGroups */ class ApiManageMessageGroupsTest extends ApiTestCase { - /** - * @var User - */ + /** @var User */ protected $user; protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ - 'wgTranslateCacheDirectory' => __DIR__ . '/../data', + 'wgTranslateCacheDirectory' => $this->getNewTempDirectory(), ] ); $this->setGroupPermissions( 'translate-admin', 'translate-manage', true ); @@ -127,7 +125,7 @@ class ApiManageMessageGroupsTest extends ApiTestCase { 'operation' => 'new', 'changesetName' => MessageChangeStorage::DEFAULT_NAME, 'changesetModified' => time() - ], null, $this->user, 'csrf' + ], null, $this->user, 'csrf' ); $sourceChanges = MessageChangeStorage::getGroupChanges( $filePath, 'testgroup-api' ); @@ -169,21 +167,10 @@ class ApiManageMessageGroupsTest extends ApiTestCase { 'operation' => 'new', 'changesetName' => MessageChangeStorage::DEFAULT_NAME, 'changesetModified' => $date->getTimestamp(), - ], null, $this->user, 'csrf' + ], null, $this->user, 'csrf' ); } - public static function tearDownAfterClass() : void { - parent::tearDownAfterClass(); - - global $wgTranslateCacheDirectory; - $tmp = $wgTranslateCacheDirectory; - $wgTranslateCacheDirectory = __DIR__ . '/../data'; - $filePath = self::getStoragePath(); - unlink( $filePath ); - $wgTranslateCacheDirectory = $tmp; - } - private static function getStoragePath() { return MessageChangeStorage::getCdbPath( MessageChangeStorage::DEFAULT_NAME ); } diff --git a/MLEB/Translate/tests/phpunit/api/ApiQueryManageMessageGroupsTest.php b/MLEB/Translate/tests/phpunit/api/ApiQueryManageMessageGroupsTest.php index bb4b440c..8b044d43 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiQueryManageMessageGroupsTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiQueryManageMessageGroupsTest.php @@ -4,22 +4,20 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\MessageSync\MessageSourceChange; +use MediaWiki\Extension\Translate\MessageSync\MessageSourceChange; /** * @group medium * @covers ApiQueryManageMessageGroups */ class ApiQueryManageMessageGroupsTest extends ApiTestCase { - /** - * @var User - */ + /** @var User */ protected $user; protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ - 'wgTranslateCacheDirectory' => __DIR__ . '/../data' + 'wgTranslateCacheDirectory' => $this->getNewTempDirectory() ] ); $this->setGroupPermissions( 'translate-admin', 'translate-manage', true ); @@ -49,7 +47,7 @@ class ApiQueryManageMessageGroupsTest extends ApiTestCase { 'mmggroupId' => 'testgroup-api', 'mmgmessageKey' => 'keyAdded1', 'mmgchangesetName' => MessageChangeStorage::DEFAULT_NAME, - ], null, false, $this->user + ], null, false, $this->user ); $apiRespose = $data[0]['query']['managemessagegroups'][0]; @@ -109,15 +107,4 @@ class ApiQueryManageMessageGroupsTest extends ApiTestCase { MessageChangeStorage::writeChanges( $changeData, self::getStoragePath() ); } - - public static function tearDownAfterClass() : void { - parent::tearDownAfterClass(); - - global $wgTranslateCacheDirectory; - $tmp = $wgTranslateCacheDirectory; - $wgTranslateCacheDirectory = __DIR__ . '/../data'; - $filePath = self::getStoragePath(); - unlink( $filePath ); - $wgTranslateCacheDirectory = $tmp; - } } diff --git a/MLEB/Translate/tests/phpunit/api/ApiQueryMessageCollectionTest.php b/MLEB/Translate/tests/phpunit/api/ApiQueryMessageCollectionTest.php index 354fbaea..4e7d3825 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiQueryMessageCollectionTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiQueryMessageCollectionTest.php @@ -5,11 +5,9 @@ * @license GPL-2.0-or-later */ -/** - * @group medium - */ +/** @group medium */ class ApiQueryMessageCollectionTest extends ApiTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setTemporaryHook( diff --git a/MLEB/Translate/tests/phpunit/api/ApiQueryMessageGroupsTest.php b/MLEB/Translate/tests/phpunit/api/ApiQueryMessageGroupsTest.php index bc797a83..227072f0 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiQueryMessageGroupsTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiQueryMessageGroupsTest.php @@ -6,12 +6,10 @@ * @license GPL-2.0-or-later */ -/** - * @group medium - */ +/** @group medium */ class ApiQueryMessageGroupsTest extends ApiTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -72,14 +70,14 @@ class ApiQueryMessageGroupsTest extends ApiTestCase { $this->assertCount( 2, $items, 'Only the two groups specified are in the api' ); $this->assertStringEndsWith( 'id', $items[0]['id'] ); $this->assertStringEndsWith( 'id', $items[1]['id'] ); - $this->assertSame( $items[0]['label'], 'thelabel' ); - $this->assertSame( $items[1]['label'], 'thelabel' ); - $this->assertSame( $items[0]['exists'], true ); - $this->assertSame( $items[1]['exists'], true ); - $this->assertSame( $items[0]['namespace'], 5 ); - $this->assertSame( $items[1]['namespace'], 5 ); - $this->assertSame( $items[0]['class'], WikiMessageGroup::class ); - $this->assertSame( $items[1]['class'], WikiMessageGroup::class ); + $this->assertSame( 'thelabel', $items[0]['label'] ); + $this->assertSame( 'thelabel', $items[1]['label'] ); + $this->assertTrue( $items[0]['exists'] ); + $this->assertTrue( $items[1]['exists'] ); + $this->assertSame( 5, $items[0]['namespace'] ); + $this->assertSame( 5, $items[1]['namespace'] ); + $this->assertSame( WikiMessageGroup::class, $items[0]['class'] ); + $this->assertSame( WikiMessageGroup::class, $items[1]['class'] ); } public function testAPIFilterAccuracy() { @@ -119,12 +117,12 @@ class ApiQueryMessageGroupsTest extends ApiTestCase { $item = $data['query']['messagegroups'][0]; $this->assertCount( 5, $item ); - $this->assertSame( $item['id'], $id ); - $this->assertSame( $item['label'], 'thelabel' ); - $this->assertSame( $item['exists'], true ); + $this->assertSame( $id, $item['id'] ); + $this->assertSame( 'thelabel', $item['label'] ); + $this->assertTrue( $item['exists'] ); $this->assertStringEndsWith( 'id', $item['id'] ); // theid, anotherid - $this->assertSame( $item['namespace'], 5 ); - $this->assertSame( $item['class'], WikiMessageGroup::class ); + $this->assertSame( 5, $item['namespace'] ); + $this->assertSame( WikiMessageGroup::class, $item['class'] ); } } diff --git a/MLEB/Translate/tests/phpunit/api/ApiTranslationReviewTest.php b/MLEB/Translate/tests/phpunit/api/ApiTranslationReviewTest.php index 3e98e97e..b0ae1eff 100644 --- a/MLEB/Translate/tests/phpunit/api/ApiTranslationReviewTest.php +++ b/MLEB/Translate/tests/phpunit/api/ApiTranslationReviewTest.php @@ -1,6 +1,5 @@ <?php /** - * * @file * @author Niklas Laxström * @license GPL-2.0-or-later @@ -8,11 +7,9 @@ use MediaWiki\MediaWikiServices; -/** - * @group Database - */ +/** @group Database */ class ApiTranslationReviewTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ diff --git a/MLEB/Translate/tests/phpunit/data/Example-result.i18n.php b/MLEB/Translate/tests/phpunit/data/Example-result.i18n.php index d7f34138..ae3aa743 100644 --- a/MLEB/Translate/tests/phpunit/data/Example-result.i18n.php +++ b/MLEB/Translate/tests/phpunit/data/Example-result.i18n.php @@ -5,52 +5,51 @@ * @file * @ingroup Extensions */ -// @codingStandardsIgnoreFile -$messages = array(); +$messages = []; -$messages['en'] = array( +$messages['en'] = [ 'translatedmessage' => 'The database has been automatically locked due to inactivity from the administrators.', - 'fuzzymessage' => 'Auto-locks the wiki database if the sysops are all inactive for some time', -); + 'fuzzymessage' => 'Auto-locks the wiki database if the sysops are all inactive for some time', +]; /** Message documentation (Message documentation) * @author Purodha * @author The Evil IP address */ -$messages['qqq'] = array( +$messages['qqq'] = [ 'fuzzymessage' => '{{desc}}', -); +]; /** Afrikaans (Afrikaans) * @author Naudefj */ -$messages['af'] = array( +$messages['af'] = [ 'translatedmessage' => 'Die databasis is outomaties gesluit omdat die administrateurs nie aktief is nie.', 'fuzzymessage' => "Sluit die wiki outomaties as die administrateurs vir 'n geruime tyd nie aktief is nie", -); +]; /** Gheg Albanian (Gegë) * @author Bresta */ -$messages['aln'] = array( +$messages['aln'] = [ 'translatedmessage' => 'Baza e të dhânave âsht bllokue automatikisht për shkak të mosaktivitetit të administruesve.', 'fuzzymessage' => 'E vetë-bllokon bazën e të dhânave nëse administruesit janë joaktiv për nji kohë të caktueme.', -); +]; /** Arabic (العربية) * @author Meno25 * @author OsamaK */ -$messages['ar'] = array( +$messages['ar'] = [ 'translatedmessage' => 'تم غلق قاعدة البيانات تلقائيا نظرا لعدم نشاط مدراء النظام.', 'fuzzymessage' => 'قفل قاعدة بيانات الويكي تلقائيا إذا كان كل مدراء النظام غير نشطين لبعض الوقت', -); +]; /** Finnish (suomi) * @author Nike the bunny */ -$messages['fi'] = array( +$messages['fi'] = [ 'translatedmsg' => 'translation', 'fuzzymsg' => 'translation', # Fuzzy -); +]; diff --git a/MLEB/Translate/tests/phpunit/data/Example.i18n.php b/MLEB/Translate/tests/phpunit/data/Example.i18n.php index 48c25d0f..46c4c0c9 100644 --- a/MLEB/Translate/tests/phpunit/data/Example.i18n.php +++ b/MLEB/Translate/tests/phpunit/data/Example.i18n.php @@ -5,44 +5,43 @@ * @file * @ingroup Extensions */ -// @codingStandardsIgnoreFile -$messages = array(); +$messages = []; -$messages['en'] = array( +$messages['en'] = [ 'translatedmessage' => 'The database has been automatically locked due to inactivity from the administrators.', - 'fuzzymessage' => 'Auto-locks the wiki database if the sysops are all inactive for some time', -); + 'fuzzymessage' => 'Auto-locks the wiki database if the sysops are all inactive for some time', +]; /** Message documentation (Message documentation) * @author Purodha * @author The Evil IP address */ -$messages['qqq'] = array( +$messages['qqq'] = [ 'fuzzymessage' => '{{desc}}', -); +]; /** Afrikaans (Afrikaans) * @author Naudefj */ -$messages['af'] = array( +$messages['af'] = [ 'translatedmessage' => 'Die databasis is outomaties gesluit omdat die administrateurs nie aktief is nie.', 'fuzzymessage' => "Sluit die wiki outomaties as die administrateurs vir 'n geruime tyd nie aktief is nie", -); +]; /** Gheg Albanian (Gegë) * @author Bresta */ -$messages['aln'] = array( +$messages['aln'] = [ 'translatedmessage' => 'Baza e të dhânave âsht bllokue automatikisht për shkak të mosaktivitetit të administruesve.', 'fuzzymessage' => 'E vetë-bllokon bazën e të dhânave nëse administruesit janë joaktiv për nji kohë të caktueme.', -); +]; /** Arabic (العربية) * @author Meno25 * @author OsamaK */ -$messages['ar'] = array( +$messages['ar'] = [ 'translatedmessage' => 'تم غلق قاعدة البيانات تلقائيا نظرا لعدم نشاط مدراء النظام.', 'fuzzymessage' => 'قفل قاعدة بيانات الويكي تلقائيا إذا كان كل مدراء النظام غير نشطين لبعض الوقت', -); +]; diff --git a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf2.yaml b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf2.yaml index 30aad12d..a4b0a979 100644 --- a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf2.yaml +++ b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf2.yaml @@ -21,7 +21,7 @@ VALIDATORS: - id: MediaWikiPlural INSERTABLES: - class: MediaWikiInsertablesSuggester + - class: MediaWikiInsertablesSuggester MANGLER: class: StringMatcher diff --git a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf3.yaml b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf3.yaml index dc738bb9..38c32133 100644 --- a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf3.yaml +++ b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf3.yaml @@ -18,7 +18,7 @@ VALIDATORS: - id: MediaWikiPlural INSERTABLES: - class: MediaWikiInsertablesSuggester + - class: MediaWikiInsertablesSuggester TAGS: optional: diff --git a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf4.yaml b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf4.yaml index 2e0eac27..eaf6f919 100644 --- a/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf4.yaml +++ b/MLEB/Translate/tests/phpunit/data/MediaWikiExtensionTest-conf4.yaml @@ -18,7 +18,7 @@ VALIDATORS: - id: MediaWikiPlural INSERTABLES: - class: MediaWikiInsertablesSuggester + - class: MediaWikiInsertablesSuggester TAGS: optional: diff --git a/MLEB/Translate/tests/phpunit/data/check-blacklist.php b/MLEB/Translate/tests/phpunit/data/check-blacklist.php index d4c2ca19..580ba437 100644 --- a/MLEB/Translate/tests/phpunit/data/check-blacklist.php +++ b/MLEB/Translate/tests/phpunit/data/check-blacklist.php @@ -1,7 +1,13 @@ <?php + $checkBlacklist = [ [ 'check' => 'plural', 'code' => [ 'en-gb' ] + ], + [ + 'message' => [ + 'regex-key-test' + ] ] ]; diff --git a/MLEB/Translate/tests/phpunit/ffs/AmdFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/AmdFFSTest.php index 4d2fb0a6..0bb8ac5f 100644 --- a/MLEB/Translate/tests/phpunit/ffs/AmdFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/AmdFFSTest.php @@ -8,12 +8,10 @@ * @license GPL-2.0-or-later */ -/** - * @see AmdFFS - */ +/** @covers \AmdFFS */ class AmdFFSTest extends MediaWikiIntegrationTestCase { - public function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->groupConfiguration = [ 'BASIC' => [ @@ -33,13 +31,9 @@ class AmdFFSTest extends MediaWikiIntegrationTestCase { protected $groupConfiguration; - /** - * @dataProvider amdProvider - */ + /** @dataProvider amdProvider */ public function testParsing( $messages, $authors, $file ) { - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new AmdFFS( $group ); $parsed = $ffs->readFromVariable( $file ); @@ -98,9 +92,7 @@ JS; public function testExport() { $collection = new MockMessageCollectionForExport(); - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new AmdFFS( $group ); $data = $ffs->writeIntoVariable( $collection ); diff --git a/MLEB/Translate/tests/phpunit/ffs/AndroidXmlFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/AndroidXmlFFSTest.php index ac415cf0..150f6b8b 100644 --- a/MLEB/Translate/tests/phpunit/ffs/AndroidXmlFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/AndroidXmlFFSTest.php @@ -1,11 +1,17 @@ <?php +declare( strict_types = 1 ); + /** - * @file * @author Niklas Laxström * @license GPL-2.0-or-later + * @covers \AndroidXmlFFS */ - class AndroidXmlFFSTest extends MediaWikiIntegrationTestCase { + private const DOCLANG = 'qqq'; + + protected function setUp(): void { + $this->setMwGlobals( 'wgTranslateDocumentationLanguageCode', self::DOCLANG ); + } protected $groupConfiguration = [ 'BASIC' => [ @@ -45,9 +51,7 @@ class AndroidXmlFFSTest extends MediaWikiIntegrationTestCase { </resources> XML; - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new AndroidXmlFFS( $group ); $parsed = $ffs->readFromVariable( $file ); @@ -73,9 +77,7 @@ XML; } public function testWrite() { - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new AndroidXmlFFS( $group ); @@ -104,19 +106,43 @@ XML; ]; $this->assertEquals( $expected, $parsed ); } + + public function testWriteDoc() { + /** @var FileBasedMessageGroup $group */ + $group = MessageGroupBase::factory( $this->groupConfiguration ); + $ffs = new AndroidXmlFFS( $group ); + + $messages = [ + 'a' => 'b', + ]; + + $collection = new MockMessageCollection( $messages, self::DOCLANG ); + + $actual = $ffs->writeIntoVariable( $collection ); + $expected = <<<'XML' +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="all"> + <string name="a">b</string> +</resources> + +XML; + $this->assertEquals( $expected, $actual ); + } } class MockMessageCollection extends MessageCollection { - public function __construct( $messages ) { + public function __construct( array $messages, string $code = 'en' ) { + $this->code = $code; $keys = array_keys( $messages ); $this->keys = array_combine( $keys, $keys ); foreach ( $messages as $key => $value ) { $m = new FatMessage( $key, $value ); $m->setTranslation( $value ); + if ( $key === 'foobar' ) { + $m->addTag( 'fuzzy' ); + } $this->messages[$key] = $m; } - - $this->messages['foobar']->addTag( 'fuzzy' ); } public function filter( $type, $condition = true, $value = null ) { diff --git a/MLEB/Translate/tests/phpunit/ffs/AppleFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/AppleFFSTest.php index 5abb5d51..eac4d660 100644 --- a/MLEB/Translate/tests/phpunit/ffs/AppleFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/AppleFFSTest.php @@ -42,9 +42,7 @@ On two lines! */ "key-with-{curlies}" = "Value that can be looked up with \"key-with-{curlies}\"."; STRINGS; - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new AppleFFS( $group ); $parsed = $ffs->readFromVariable( $file ); @@ -62,9 +60,7 @@ STRINGS; $this->assertEquals( $expected, $parsed ); } - /** - * @dataProvider rowValuesProvider - */ + /** @dataProvider rowValuesProvider */ public function testRowRoundtrip( $key, $value, $comment ) { $write = AppleFFS::writeRow( $key, $value ); // Trim the trailing newline diff --git a/MLEB/Translate/tests/phpunit/ffs/AppleInfoPlistFfsTest.php b/MLEB/Translate/tests/phpunit/ffs/AppleInfoPlistFfsTest.php index 05220dc0..d5295da6 100644 --- a/MLEB/Translate/tests/phpunit/ffs/AppleInfoPlistFfsTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/AppleInfoPlistFfsTest.php @@ -8,9 +8,7 @@ * @file */ -/** - * @covers AppleInfoPlistFfs - */ +/** @covers AppleInfoPlistFfs */ class AppleInfoPlistFfsTest extends MediaWikiIntegrationTestCase { protected $groupConfigurationInfoPList = [ diff --git a/MLEB/Translate/tests/phpunit/ffs/DtdFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/DtdFFSTest.php index 357314f2..b5bb5ff3 100644 --- a/MLEB/Translate/tests/phpunit/ffs/DtdFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/DtdFFSTest.php @@ -38,9 +38,7 @@ class DtdFFSTest extends MediaWikiIntegrationTestCase { "Retro"> DTD; - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new DtdFFS( $group ); $parsed = $ffs->readFromVariable( $file ); diff --git a/MLEB/Translate/tests/phpunit/ffs/GettextFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/GettextFFSTest.php index 291164ba..bf8c0606 100644 --- a/MLEB/Translate/tests/phpunit/ffs/GettextFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/GettextFFSTest.php @@ -8,13 +8,11 @@ * @license GPL-2.0-or-later */ -/** - * @see GettextFFS - */ +/** @covers \GettextFFS */ class GettextFFSTest extends MediaWikiIntegrationTestCase { protected $groupConfiguration; - public function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->groupConfiguration = [ 'BASIC' => [ @@ -31,9 +29,7 @@ class GettextFFSTest extends MediaWikiIntegrationTestCase { ]; } - /** - * @dataProvider provideMangling - */ + /** @dataProvider provideMangling */ public function testMangling( $expected, $item, $algo ) { $this->assertEquals( $expected, GettextFFS::generateKeyFromItem( $item, $algo ) ); } @@ -156,9 +152,7 @@ GETTEXT; ); } - /** - * @dataProvider provideShouldOverwrite - */ + /** @dataProvider provideShouldOverwrite */ public function testShouldOverwrite( $a, $b, $expected, $comment ) { $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new GettextFFS( $group ); diff --git a/MLEB/Translate/tests/phpunit/ffs/IniFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/IniFFSTest.php index 0af4cd9a..b1c218f5 100644 --- a/MLEB/Translate/tests/phpunit/ffs/IniFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/IniFFSTest.php @@ -27,9 +27,7 @@ class IniFFSTest extends MediaWikiIntegrationTestCase { public function testParsing() { $file = file_get_contents( __DIR__ . '/../data/IniFFSTest1.ini' ); - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new IniFFS( $group ); @@ -48,6 +46,9 @@ class IniFFSTest extends MediaWikiIntegrationTestCase { 'AUTHORS' => [ 'The king of very small kingdom' ] ]; $this->assertEquals( $expected, $parsed ); + + $invalidContent = 'Invalid-Ini-Content'; + $this->assertFalse( IniFFS::isValid( $invalidContent ) ); } public function testExport() { @@ -56,9 +57,7 @@ class IniFFSTest extends MediaWikiIntegrationTestCase { $file = str_replace( '$wgSitename', $wgSitename, $file ); $collection = new MockMessageCollectionForExport(); - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new IniFFS( $group ); $this->assertEquals( $file, $ffs->writeIntoVariable( $collection ) ); diff --git a/MLEB/Translate/tests/phpunit/ffs/JavaFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/JavaFFSTest.php index cef493e0..685475cd 100644 --- a/MLEB/Translate/tests/phpunit/ffs/JavaFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/JavaFFSTest.php @@ -39,9 +39,7 @@ key\ with\ spaces = Value that can be looked up with "key with spaces". key-with-{curlies} = Value that can be looked up with "key-with-{curlies}". PROPERTIES; - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new JavaFFS( $group ); $parsed = $ffs->readFromVariable( $file ); @@ -57,9 +55,7 @@ PROPERTIES; $this->assertEquals( $expected, $parsed ); } - /** - * @dataProvider rowValuesProvider - */ + /** @dataProvider rowValuesProvider */ public function testRowRoundtrip( $key, $sep, $value, $comment ) { $write = JavaFFS::writeRow( $key, $sep, $value ); // Trim the trailing newline diff --git a/MLEB/Translate/tests/phpunit/ffs/JsonFFSTest.php b/MLEB/Translate/tests/phpunit/ffs/JsonFFSTest.php index 37f7a092..4fd15049 100644 --- a/MLEB/Translate/tests/phpunit/ffs/JsonFFSTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/JsonFFSTest.php @@ -8,12 +8,10 @@ * @license GPL-2.0-or-later */ -/** - * @see JsonFFS - */ +/** @covers \JsonFFS */ class JsonFFSTest extends MediaWikiIntegrationTestCase { - public function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->groupConfiguration = [ 'BASIC' => [ @@ -33,13 +31,9 @@ class JsonFFSTest extends MediaWikiIntegrationTestCase { protected $groupConfiguration; - /** - * @dataProvider jsonProvider - */ + /** @dataProvider jsonProvider */ public function testParsing( $messages, $authors, $file ) { - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new JsonFFS( $group ); $parsed = $ffs->readFromVariable( $file ); @@ -112,9 +106,7 @@ JSON; public function testExport() { $collection = new MockMessageCollectionForExport(); - /** - * @var FileBasedMessageGroup $group - */ + /** @var FileBasedMessageGroup $group */ $group = MessageGroupBase::factory( $this->groupConfiguration ); $ffs = new JsonFFS( $group ); $data = $ffs->writeIntoVariable( $collection ); diff --git a/MLEB/Translate/tests/phpunit/ffs/MediaWikiExtensionsTest.php b/MLEB/Translate/tests/phpunit/ffs/MediaWikiExtensionsTest.php index db823da8..a2dc72eb 100644 --- a/MLEB/Translate/tests/phpunit/ffs/MediaWikiExtensionsTest.php +++ b/MLEB/Translate/tests/phpunit/ffs/MediaWikiExtensionsTest.php @@ -1,4 +1,5 @@ <?php + /** * Test for parsing the special definition file for mediawiki-extensions * @author Niklas Laxström @@ -16,8 +17,8 @@ class MediaWikiExtensionsTest extends PHPUnit\Framework\TestCase { $list = $deps = $autoload = []; $foo->register( $list, $deps, $autoload ); - $this->assertSame( 1, count( $deps ), 'A dependency to definition file was added' ); - $this->assertEquals( 5, count( $list ), 'Right number of groups were created' ); + $this->assertCount( 1, $deps, 'A dependency to definition file was added' ); + $this->assertCount( 5, $list, 'Right number of groups were created' ); $this->assertArrayHasKey( 'ext-wikimediamessages', $list ); $expected = TranslateYaml::load( __DIR__ . '/../data/MediaWikiExtensionTest-conf2.yaml' ); @@ -33,8 +34,8 @@ class MediaWikiExtensionsTest extends PHPUnit\Framework\TestCase { $this->assertArrayHasKey( 'ext-languagesmodified', $list ); $languages = $list['ext-languagesmodified']->getTranslatableLanguages(); - $this->assertArrayHasKey( 'foo', $languages, 'Whitelisted language is available' ); - $this->assertArrayNotHasKey( 'bar', $languages, 'Blacklisted language is not available' ); + $this->assertArrayHasKey( 'foo', $languages, 'Included language is available' ); + $this->assertArrayNotHasKey( 'bar', $languages, 'Excluded language is not available' ); $this->assertArrayHasKey( 'de', $languages, 'Default language is available' ); $this->assertArrayHasKey( 'ext-languagesset', $list ); diff --git a/MLEB/Translate/tests/phpunit/helpers/TranslatablePageTestTrait.php b/MLEB/Translate/tests/phpunit/helpers/TranslatablePageTestTrait.php index d3e0e744..bed15548 100644 --- a/MLEB/Translate/tests/phpunit/helpers/TranslatablePageTestTrait.php +++ b/MLEB/Translate/tests/phpunit/helpers/TranslatablePageTestTrait.php @@ -29,7 +29,7 @@ trait TranslatablePageTestTrait { * @param string $title * @param string $content * @param User $creator - * @return void + * @return TranslatablePage */ public function createMarkedTranslatablePage( string $title, string $content, User $creator diff --git a/MLEB/Translate/tests/phpunit/messagegroups/AggregateMessageGroupLoaderTest.php b/MLEB/Translate/tests/phpunit/messagegroups/AggregateMessageGroupLoaderTest.php index de375715..3dd40e24 100644 --- a/MLEB/Translate/tests/phpunit/messagegroups/AggregateMessageGroupLoaderTest.php +++ b/MLEB/Translate/tests/phpunit/messagegroups/AggregateMessageGroupLoaderTest.php @@ -1,14 +1,7 @@ <?php -/** - * @group Database - */ +/** @group Database */ class AggregateMessageGroupLoaderTest extends PHPUnit\Framework\TestCase { - /** - * @var AggregateMessageGroup - */ - protected $mgAggregateLoader; - public function testCacheCalls() { /** @var MessageGroupWANCache $mockMgWANCache */ $mockMgWANCache = $this->getMockBuilder( MessageGroupWANCache::class ) diff --git a/MLEB/Translate/tests/phpunit/messagegroups/FileBasedMessageGroupLoaderTest.php b/MLEB/Translate/tests/phpunit/messagegroups/FileBasedMessageGroupLoaderTest.php index b1364dc1..fff76def 100644 --- a/MLEB/Translate/tests/phpunit/messagegroups/FileBasedMessageGroupLoaderTest.php +++ b/MLEB/Translate/tests/phpunit/messagegroups/FileBasedMessageGroupLoaderTest.php @@ -1,12 +1,10 @@ <?php class FileBasedMessageGroupLoaderTest extends MediaWikiIntegrationTestCase { - /** - * @var FileBasedMessageGroupLoader - */ + /** @var FileBasedMessageGroupLoader */ protected $mgFileLoader; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $conf = [ diff --git a/MLEB/Translate/tests/phpunit/messagegroups/MessageGroupLoaderTest.php b/MLEB/Translate/tests/phpunit/messagegroups/MessageGroupLoaderTest.php index 4d4bcc37..74df03cb 100644 --- a/MLEB/Translate/tests/phpunit/messagegroups/MessageGroupLoaderTest.php +++ b/MLEB/Translate/tests/phpunit/messagegroups/MessageGroupLoaderTest.php @@ -1,9 +1,10 @@ <?php + class MessageGroupLoaderTest extends MediaWikiIntegrationTestCase { protected $cacheLoaderMock; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->cacheLoaderMock = $this->createMock( MockCacheMessageGroupLoader::class ); diff --git a/MLEB/Translate/tests/phpunit/messagegroups/TranslatablePageMessageGroupStoreTest.php b/MLEB/Translate/tests/phpunit/messagegroups/TranslatablePageMessageGroupStoreTest.php index a9395d1b..d6877db9 100644 --- a/MLEB/Translate/tests/phpunit/messagegroups/TranslatablePageMessageGroupStoreTest.php +++ b/MLEB/Translate/tests/phpunit/messagegroups/TranslatablePageMessageGroupStoreTest.php @@ -1,16 +1,13 @@ <?php -/** - * @group Database - */ + +/** @group Database */ class TranslatablePageMessageGroupStoreTest extends MediaWikiIntegrationTestCase { use TranslatablePageTestTrait; - /** - * @var TranslatablePageMessageGroupStore - */ + /** @var TranslatablePageMessageGroupStore */ protected $mgTranslateStore; - public function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ diff --git a/MLEB/Translate/tests/phpunit/mocks/MockCacheMessageGroupLoader.php b/MLEB/Translate/tests/phpunit/mocks/MockCacheMessageGroupLoader.php index fcb386fb..11278337 100644 --- a/MLEB/Translate/tests/phpunit/mocks/MockCacheMessageGroupLoader.php +++ b/MLEB/Translate/tests/phpunit/mocks/MockCacheMessageGroupLoader.php @@ -1,4 +1,5 @@ <?php + class MockCacheMessageGroupLoader extends MessageGroupLoader implements CachedMessageGroupLoader { diff --git a/MLEB/Translate/tests/phpunit/mocks/MockCustomInsertableSuggester.php b/MLEB/Translate/tests/phpunit/mocks/MockCustomInsertableSuggester.php new file mode 100644 index 00000000..350e6643 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/mocks/MockCustomInsertableSuggester.php @@ -0,0 +1,10 @@ +<?php +declare( strict_types = 1 ); + +use MediaWiki\Extension\Translate\TranslatorInterface\Insertable\InsertablesSuggester; + +class MockCustomInsertableSuggester implements InsertablesSuggester { + public function getInsertables( string $text ): array { + return [ new Insertable( 'test' ) ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/mocks/MockValidators.php b/MLEB/Translate/tests/phpunit/mocks/MockValidators.php index 9f066b68..14e11a70 100644 --- a/MLEB/Translate/tests/phpunit/mocks/MockValidators.php +++ b/MLEB/Translate/tests/phpunit/mocks/MockValidators.php @@ -7,9 +7,9 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\Validation\MessageValidator; -use MediaWiki\Extensions\Translate\Validation\ValidationIssue; -use MediaWiki\Extensions\Translate\Validation\ValidationIssues; +use MediaWiki\Extension\Translate\Validation\MessageValidator; +use MediaWiki\Extension\Translate\Validation\ValidationIssue; +use MediaWiki\Extension\Translate\Validation\ValidationIssues; class MockTranslateValidator implements MessageValidator { public function getIssues( TMessage $message, string $targetLanguage ): ValidationIssues { diff --git a/MLEB/Translate/tests/phpunit/mocks/MockWikiMessageGroup.php b/MLEB/Translate/tests/phpunit/mocks/MockWikiMessageGroup.php index ad257d57..fc50c4b2 100644 --- a/MLEB/Translate/tests/phpunit/mocks/MockWikiMessageGroup.php +++ b/MLEB/Translate/tests/phpunit/mocks/MockWikiMessageGroup.php @@ -1,4 +1,7 @@ <?php + +use MediaWiki\Extension\Translate\Validation\ValidationRunner; + /** * This file contains multiple unmanaged message group implementation. * @@ -33,7 +36,7 @@ class MockWikiMessageGroup extends WikiMessageGroup { */ class MockWikiValidationMessageGroup extends MockWikiMessageGroup { public function getValidator() { - $validator = new MessageValidator( $this->getId() ); + $validator = new ValidationRunner( $this->getId() ); $validator->setValidators( [ [ 'class' => AnotherMockTranslateValidator::class ], [ diff --git a/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSubClass.php b/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSubClass.php new file mode 100644 index 00000000..0170c536 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSubClass.php @@ -0,0 +1,42 @@ +<?php +declare( strict_types = 1 ); + +use MediaWiki\Extension\Translate\Utilities\Json\JsonUnserializableTrait; + +/** + * Testing class for JsonCodec unit tests. + * Remove once we need to support only MW >= 1.36 + * See Change-Id: I5433090ae8e2b3f2a4590cc404baf838025546ce + * + * @license GPL-2.0-or-later + */ +class MockJsonUnserializableSubClass extends MockJsonUnserializableSuperClass { + use JsonUnserializableTrait; + + /** @var string */ + private $subClassField; + + public function __construct( string $superClassFieldValue, string $subClassFieldValue ) { + parent::__construct( $superClassFieldValue ); + $this->subClassField = $subClassFieldValue; + } + + public function getSubClassField(): string { + return $this->subClassField; + } + + /** + * @param string[] $json + * @return self + */ + public static function newFromJsonArray( array $json ) { + return new self( $json['super_class_field'], $json['sub_class_field'] ); + } + + /** @return string[] */ + protected function toJsonArray(): array { + return parent::toJsonArray() + [ + 'sub_class_field' => $this->getSubClassField() + ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSuperClass.php b/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSuperClass.php new file mode 100644 index 00000000..1da38f25 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/mocks/json/MockJsonUnserializableSuperClass.php @@ -0,0 +1,42 @@ +<?php +declare( strict_types = 1 ); + +use MediaWiki\Extension\Translate\Utilities\Json\JsonUnserializable; +use MediaWiki\Extension\Translate\Utilities\Json\JsonUnserializableTrait; + +/** + * Testing class for JsonCodec unit tests. + * Remove once we need to support only MW >= 1.36 + * See Change-Id: I5433090ae8e2b3f2a4590cc404baf838025546ce + * + * @license GPL-2.0-or-later + */ +class MockJsonUnserializableSuperClass implements JsonUnserializable, JsonSerializable { + use JsonUnserializableTrait; + + /** @var string */ + private $superClassField; + + public function __construct( string $superClassFieldValue ) { + $this->superClassField = $superClassFieldValue; + } + + public function getSuperClassField(): string { + return $this->superClassField; + } + + /** + * @param string[] $json + * @return self + */ + public static function newFromJsonArray( array $json ) { + return new self( $json['super_class_field'] ); + } + + /** @return string[] */ + protected function toJsonArray(): array { + return [ + 'super_class_field' => $this->getSuperClassField() + ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/tag/PageTranslationHooksTest.php b/MLEB/Translate/tests/phpunit/tag/PageTranslationHooksTest.php index 372f15d6..06d4f0da 100644 --- a/MLEB/Translate/tests/phpunit/tag/PageTranslationHooksTest.php +++ b/MLEB/Translate/tests/phpunit/tag/PageTranslationHooksTest.php @@ -15,7 +15,7 @@ use MediaWiki\Revision\RevisionRecord; * @group medium */ class PageTranslationHooksTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -95,15 +95,14 @@ class PageTranslationHooksTest extends MediaWikiIntegrationTestCase { // Check that our code works for translation pages $parserOutput = $parser->parse( 'fi-pupu', $translationPageTitle, $options ); $actual = $parserOutput->getExtensionData( 'translate-translation-page' ); - $expected = [ - 'sourcepagetitle' => $translatablePageTitle, - 'languagecode' => 'fi', - 'messagegroupid' => 'page-Vuosaari', - ]; - $this->assertTrue( is_array( $actual ), 'Extension data is set on marked page' ); + $this->assertIsArray( $actual, 'Extension data is set on marked page' ); + $actualTitle = Title::makeTitle( + $actual[ 'sourcepagetitle' ][ 'namespace' ], + $actual[ 'sourcepagetitle' ][ 'dbkey' ] + ); $this->assertSame( 'Vuosaari', - $actual[ 'sourcepagetitle' ]->getPrefixedText(), + $actualTitle->getPrefixedText(), 'Source page title is correct' ); $this->assertSame( @@ -145,9 +144,7 @@ class PageTranslationHooksTest extends MediaWikiIntegrationTestCase { "translation with errors is saved if user with 'translate-manage' permission is translating." ); } - /** - * @covers PageTranslationHooks::updateTranstagOnNullRevisions - */ + /** @covers PageTranslationHooks::updateTranstagOnNullRevisions */ public function testTagNullRevision() { $title = Title::newFromText( 'translated' ); $status = $this->editPage( diff --git a/MLEB/Translate/tests/phpunit/tag/PageTranslationParserTest.php b/MLEB/Translate/tests/phpunit/tag/PageTranslationParserTest.php index 7708b121..99909715 100644 --- a/MLEB/Translate/tests/phpunit/tag/PageTranslationParserTest.php +++ b/MLEB/Translate/tests/phpunit/tag/PageTranslationParserTest.php @@ -1,59 +1,67 @@ <?php -/** - * @author Niklas Laxström - * @copyright Copyright © 2010-2013, Niklas Laxström - * @license GPL-2.0-or-later - * @file - */ +declare( strict_types = 1 ); + +use MediaWiki\Extension\Translate\PageTranslation\ParserOutput; +use MediaWiki\Extension\Translate\PageTranslation\ParsingFailure; +use MediaWiki\Extension\Translate\PageTranslation\TestingParsingPlaceholderFactory; +use MediaWiki\Extension\Translate\PageTranslation\TranslatablePageParser; +use MediaWiki\Extension\Translate\PageTranslation\TranslationPage; /** * Custom testing framework for page translation parser. * @ingroup PageTranslation - * @group Database + * @author Niklas Laxström + * @license GPL-2.0-or-later */ class PageTranslationParserTest extends MediaWikiIntegrationTestCase { public static function provideTestFiles() { $dir = __DIR__; $testFiles = glob( "$dir/pagetranslation/*.ptfile" ); foreach ( $testFiles as $i => $file ) { - $testFiles[$i] = [ $file ]; + $testFiles[$i] = [ basename( $file, '.ptfile' ), $file ]; } return $testFiles; } - /** - * @dataProvider provideTestFiles - */ - public function testParsing( $file ) { - $filename = basename( $file ); - list( $pagename, ) = explode( '.', $filename, 2 ); - $title = Title::newFromText( $pagename ); - $translatablePage = TranslatablePage::newFromText( $title, file_get_contents( $file ) ); - - $pattern = dirname( $file ) . "/$pagename"; - - if ( $filename === 'FailNotAtomic.ptfile' ) { + /** @dataProvider provideTestFiles */ + public function testParsing( string $name, string $file ) { + if ( $name === 'FailNotAtomic' ) { $this->markTestSkipped( 'Extended validation not yet implemented' ); } - $failureExpected = strpos( $pagename, 'Fail' ) === 0; + if ( $name !== 'Whitespace' ) { + $this->markTestSkipped( 'Extended validation not yet implemented' ); + } - if ( $failureExpected ) { - $this->expectException( TPException::class ); + if ( strpos( $name, 'Fail' ) === 0 ) { + $this->expectException( ParsingFailure::class ); } - $parse = $translatablePage->getParse(); - $this->assertInstanceOf( 'TPParse', $parse ); + $title = Title::newFromText( $name ); + $inputSourceText = file_get_contents( $file ); + $parser = new TranslatablePageParser( new TestingParsingPlaceholderFactory() ); + $parserOutput = $parser->parse( $inputSourceText ); + + $pattern = dirname( $file ) . "/$name"; if ( file_exists( "$pattern.ptsource" ) ) { - $source = $parse->getSourcePageText(); - $this->assertEquals( file_get_contents( "$pattern.ptsource" ), $source ); + $source = $parserOutput->sourcePageTextForSaving(); + $this->assertSame( + file_get_contents( "$pattern.ptsource" ), + $source, + 'Marked source text is as expected' + ); } if ( file_exists( "$pattern.pttarget" ) ) { - $target = $parse->getTranslationPageText( [] ); - $this->assertEquals( file_get_contents( "$pattern.pttarget" ), $target ); + $translationPage = $this->getTranslationPage( $title, $parserOutput ); + $target = $translationPage->generateSourceFromTranslations( [] ); + $this->assertEquals( + file_get_contents( "$pattern.pttarget" ), + $target, + 'Generated translation page text is as expected' + ); } // Custom tests written in php @@ -61,4 +69,23 @@ class PageTranslationParserTest extends MediaWikiIntegrationTestCase { require "$pattern.pttest"; } } + + // This is copy of TranslatablePage::getTranslationPage, to mock WikiPageMessageGroup + private function getTranslationPage( + Title $title, + ParserOutput $parserOutput + ): TranslationPage { + $showOutdated = false; + $wrapUntranslated = false; + + return new TranslationPage( + $parserOutput, + $this->createMock( WikiPageMessageGroup::class ), + Language::factory( 'en' ), + Language::factory( 'en' ), + $showOutdated, + $wrapUntranslated, + $title->getPrefixedDBkey() . '/' + ); + } } diff --git a/MLEB/Translate/tests/phpunit/tag/PageTranslationTaggingTest.php b/MLEB/Translate/tests/phpunit/tag/PageTranslationTaggingTest.php index 636e486b..264e813c 100644 --- a/MLEB/Translate/tests/phpunit/tag/PageTranslationTaggingTest.php +++ b/MLEB/Translate/tests/phpunit/tag/PageTranslationTaggingTest.php @@ -7,7 +7,7 @@ use MediaWiki\MediaWikiServices; * @group medium */ class PageTranslationTaggingTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ @@ -34,7 +34,7 @@ class PageTranslationTaggingTest extends MediaWikiIntegrationTestCase { $translatablePage = TranslatablePage::newFromTitle( $title ); $content = ContentHandler::makeContent( 'kissa', $title ); - $page->doEditContent( $content, 'Test case' ); + $page->doEditContent( $content, 'Test case' ); $this->assertFalse( $translatablePage->getReadyTag(), 'No ready tag was added' ); $this->assertFalse( $translatablePage->getMarkedTag(), 'No marked tag was added' ); diff --git a/MLEB/Translate/tests/phpunit/tag/TranslatablePageIntegrationTest.php b/MLEB/Translate/tests/phpunit/tag/TranslatablePageIntegrationTest.php index e901e56a..ed1c42e9 100644 --- a/MLEB/Translate/tests/phpunit/tag/TranslatablePageIntegrationTest.php +++ b/MLEB/Translate/tests/phpunit/tag/TranslatablePageIntegrationTest.php @@ -11,7 +11,7 @@ use MediaWiki\MediaWikiServices; class TranslatablePageIntegrationTest extends MediaWikiIntegrationTestCase { use TranslatablePageTestTrait; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ diff --git a/MLEB/Translate/tests/phpunit/tag/pagetranslation/NowikiOnly.pttest b/MLEB/Translate/tests/phpunit/tag/pagetranslation/NowikiOnly.pttest index 69d14eaa..0923d10e 100644 --- a/MLEB/Translate/tests/phpunit/tag/pagetranslation/NowikiOnly.pttest +++ b/MLEB/Translate/tests/phpunit/tag/pagetranslation/NowikiOnly.pttest @@ -2,6 +2,4 @@ if ( !defined( 'MEDIAWIKI' ) ) die(); -if ( $parse->countSections() !== 0 ) { - $this->fail( "Testfile $filename failed misc tests... number of sections should be zero" ); -} +$this->assertEmpty( $parserOutput->units(), 'number of sections should be zero' ); diff --git a/MLEB/Translate/tests/phpunit/translationaids/TranslationAidDataProviderTest.php b/MLEB/Translate/tests/phpunit/translationaids/TranslationAidDataProviderTest.php index 0d3e19c6..b82c4486 100644 --- a/MLEB/Translate/tests/phpunit/translationaids/TranslationAidDataProviderTest.php +++ b/MLEB/Translate/tests/phpunit/translationaids/TranslationAidDataProviderTest.php @@ -6,7 +6,7 @@ */ class TranslationAidDataProviderTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setMwGlobals( [ 'wgTranslateMessageNamespaces' => [ NS_MEDIAWIKI ] diff --git a/MLEB/Translate/tests/phpunit/unit/PageTranslation/ParserOutputTest.php b/MLEB/Translate/tests/phpunit/unit/PageTranslation/ParserOutputTest.php new file mode 100644 index 00000000..93f35c8d --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/PageTranslation/ParserOutputTest.php @@ -0,0 +1,98 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\PageTranslation; + +use InvalidArgumentException; +use Language; +use MediaWikiUnitTestCase; + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\PageTranslation\ParserOutput + */ +class ParserOutputTest extends MediaWikiUnitTestCase { + public function testConstructor() { + $actual = new ParserOutput( '', [], [] ); + $this->assertInstanceOf( ParserOutput::class, $actual ); + } + + public function testConstructorFail() { + $this->expectException( InvalidArgumentException::class ); + $actual = new ParserOutput( '', [ (object)[] ], [] ); + $this->assertInstanceOf( ParserOutput::class, $actual ); + } + + public function testConstructorFail2() { + $this->expectException( InvalidArgumentException::class ); + $actual = new ParserOutput( '', [], [ (object)[] ] ); + $this->assertInstanceOf( ParserOutput::class, $actual ); + } + + public function testSourcePageTemplate() { + $output = new ParserOutput( + 'A<0>B', + [ '<0>' => new Section( '<translate>', '<1>', '</translate>' ) ], + [] + ); + + $this->assertSame( 'A<translate><1></translate>B', $output->sourcePageTemplate() ); + } + + public function testTranslationPageTemplate() { + $output = new ParserOutput( + 'A<0>B', + [ '<0>' => new Section( '<translate>', '<1>', '</translate>' ) ], + [] + ); + + $this->assertSame( 'A<1>B', $output->translationPageTemplate() ); + } + + public function testUnits() { + $units = []; + $units['<1>'] = new TranslationUnit(); + + $output = new ParserOutput( + 'A<0>B', + [ '<0>' => new Section( '<translate>', '<1>', '</translate>' ) ], + $units + ); + + $this->assertSame( $units, $output->units() ); + } + + public function testSourcePageTextForRendering() { + $units = []; + $units['<1>'] = new TranslationUnit(); + $units['<1>']->text = 'Hello'; + + $output = new ParserOutput( + 'A<0>B', + [ '<0>' => new Section( '<translate>', '<1>', '</translate>' ) ], + $units + ); + + $language = $this->createStub( Language::class ); + $language->method( 'getHtmlCode' )->willReturn( 'en-GB' ); + + $this->assertSame( 'AHelloB', $output->sourcePageTextForRendering( $language ) ); + } + + public function testSourcePageTextForSaving() { + $units = []; + $units['<1>'] = new TranslationUnit(); + $units['<1>']->text = 'Hello'; + $units['<1>']->id = 'abc'; + $units['<1>']->setIsInline( true ); + + $output = new ParserOutput( + 'A<0>B', + [ '<0>' => new Section( '<translate>', '<1>', '</translate>' ) ], + $units + ); + + $this->assertSame( 'A<translate><!--T:abc--> Hello</translate>B', $output->sourcePageTextForSaving() ); + } +} diff --git a/MLEB/Translate/tests/phpunit/unit/PageTranslation/SectionTest.php b/MLEB/Translate/tests/phpunit/unit/PageTranslation/SectionTest.php new file mode 100644 index 00000000..1cfcb5f1 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/PageTranslation/SectionTest.php @@ -0,0 +1,23 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\PageTranslation; + +use MediaWikiUnitTestCase; + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\PageTranslation\Section + */ +class SectionTest extends MediaWikiUnitTestCase { + public function test() { + $section = new Section( '<translate>', '2045903458', '</translate>' ); + $this->assertSame( '2045903458', $section->contents() ); + $this->assertSame( '<translate>2045903458</translate>', $section->wrappedContents() ); + + $section = new Section( '<translate>', "\n\n<0>\n\n", '</translate>' ); + $this->assertSame( "\n<0>\n", $section->contents() ); + $this->assertSame( "<translate>\n\n<0>\n\n</translate>", $section->wrappedContents() ); + } +} diff --git a/MLEB/Translate/tests/phpunit/insertables/TranslatablePageInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslatablePageInsertablesSuggesterTest.php index 7d3e6198..fbf36125 100644 --- a/MLEB/Translate/tests/phpunit/insertables/TranslatablePageInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslatablePageInsertablesSuggesterTest.php @@ -5,10 +5,14 @@ * @license GPL-2.0-or-later */ -class TranslatablePageInsertablesSuggesterTest extends PHPUnit\Framework\TestCase { - /** - * @dataProvider getInsertablesProvider - */ +namespace MediaWiki\Extension\Translate\PageTranslation; + +use MediaWiki\Extension\Translate\TranslatorInterface\Insertable\Insertable; +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\PageTranslation\TranslatablePageInsertablesSuggester */ +class TranslatablePageInsertablesSuggesterTest extends MediaWikiUnitTestCase { + /** @dataProvider getInsertablesProvider */ public function testGetInsertables( $input, $expected ) { $suggester = new TranslatablePageInsertablesSuggester(); $this->assertEquals( $expected, $suggester->getInsertables( $input ) ); diff --git a/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslatablePageParserTest.php b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslatablePageParserTest.php new file mode 100644 index 00000000..17a1a706 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslatablePageParserTest.php @@ -0,0 +1,349 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\PageTranslation; + +use MediaWiki\Extension\Translate\Utilities\ParsingPlaceholderFactory; +use MediaWikiUnitTestCase; + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\PageTranslation\TranslatablePageParser + */ +class TranslatablePageParserTest extends MediaWikiUnitTestCase { + /** @dataProvider provideTestContainsMarkup */ + public function testContainsMarkup( string $input, bool $expected ) { + $parser = new TranslatablePageParser( new ParsingPlaceholderFactory() ); + $this->assertSame( $expected, $parser->containsMarkup( $input ) ); + } + + public function provideTestContainsMarkup() { + yield [ 'Plain page', false ]; + + yield [ '<languages/>', false ]; + + yield [ '<translate>Board, Run!</translate>', true ]; + + yield [ '<translate nowrap>Board, Run!</translate>', true ]; + + yield [ '<translate unknown="attributes">Board, Run!</translate>', true ]; + + yield [ '</translate>', true ]; + + yield [ '<nowiki><translate></nowiki>', false ]; + } + + /** @dataProvider provideTestCleanupTags */ + public function testCleanupTags( string $input, string $expected ) { + $parser = new TranslatablePageParser( new ParsingPlaceholderFactory() ); + $this->assertSame( $expected, $parser->cleanupTags( $input ) ); + } + + public function provideTestCleanupTags() { + yield 'Unbalanced tag in a section preview' => [ + "== Hello ==\n</translate>", + '== Hello ==', + ]; + + yield 'Unbalanced tags, no whitespace' => [ + "</translate><translate>", + '', + ]; + + yield 'Balanced tags, non-removable whitespace' => [ + "1\n2<translate>3\n4</translate>5\n6", + "1\n23\n45\n6", + ]; + + yield 'Balanced tags, removable whitespace' => [ + "1<translate>\n\n</translate>2", + '12', + ]; + + yield 'Old style translation variable tag is collapsed' => [ + '[[<tvar|wmf>Special:MyLanguage/Wikimedia Foundation</>|Wikimedia Foundation]].', + '[[Special:MyLanguage/Wikimedia Foundation|Wikimedia Foundation]].', + ]; + + yield 'Translation variable tag is collapsed' => [ + '[[<tvar name=wmf>Special:MyLanguage/Wikimedia Foundation</tvar>|Wikimedia Foundation]].', + '[[Special:MyLanguage/Wikimedia Foundation|Wikimedia Foundation]].', + ]; + + yield 'Tag inside a nowiki is retained' => [ + 'You can use the <nowiki><translate></nowiki> tag.', + 'You can use the <nowiki><translate></nowiki> tag.', + ]; + + yield 'Broken tag is retained' => [ + 'What if I <translate and </translate>.', + 'What if I <translate and .', + ]; + + yield 'Tag with nowrap is removed' => [ + '<abbr title="<translate nowrap>Careful unselfish true engineer</translate>">CUTE</abbr>', + '<abbr title="Careful unselfish true engineer">CUTE</abbr>', + ]; + + yield 'No content to remove' => [ + 'Plain page', + 'Plain page', + ]; + + yield 'Language tag should not be removed by this method' => [ + '<languages/>', + '<languages/>', + ]; + + yield 'Unclosed tag is removed' => [ + '<translate>No worries, I will try to remember to close this tag', + 'No worries, I will try to remember to close this tag', + + ]; + + yield 'Complex old translation variable syntax is parsed and replaced with contents' => [ + '<translate nowrap>I have <tvar|!><:D></></translate>!', + 'I have <:D>!', + ]; + + yield 'Complex translation variable syntax is parsed and replaced with contents' => [ + '<translate nowrap>I have <tvar name="--$"><:D></tvar></translate>!', + 'I have <:D>!', + ]; + + yield 'No extra newlines is added' => [ + 'A<translate>B<translate>C</translate>D</translate>E', + 'ABCDE', + ]; + + yield 'Reasonable amount of newlines is stripped' => [ + "A\n<translate>\n\nB</translate>\nC\n<translate>D\n\n\n\n</translate>E", + "A\n\nB\nC\nD\n\n\nE", + + ]; + + yield 'Section markers are removed from headings' => [ + "<translate>\n== Head of the header == <!--T:1-->\n</translate>", + "== Head of the header ==", + ]; + + yield 'Section markers are removed, but not other text' => [ + ' <!--T:10--> text <!--T:11--> more text <!--T:12--> even more', + ' text more text even more', + ]; + } + + /** @dataProvider provideTestParse */ + public function testParse( + string $input, + string $expectedTranslationTemplate, + string $expectedSourceTemplate, + array $expectedUnits + ) { + $parser = new TranslatablePageParser( new TestingParsingPlaceholderFactory() ); + $output = $parser->parse( $input ); + $this->assertSame( $expectedTranslationTemplate, $output->translationPageTemplate() ); + $this->assertSame( $expectedSourceTemplate, $output->sourcePageTemplate() ); + $this->assertEquals( $expectedUnits, $output->units() ); + } + + public function provideTestParse() { + // Test case 1 // + $s1 = new TranslationUnit(); + $s1->text = '== Unit tests =='; + $s1->id = -1; + + $s2 = new TranslationUnit(); + $s2->text = 'Introduction to unit tests.'; + $s2->id = -1; + + $s3 = new TranslationUnit(); + $s3->text = 'They are fun.'; + $s3->id = -1; + + $s4 = new TranslationUnit(); + $s4->text = 'Smilie'; + $s4->id = -1; + $s4->setCanWrap( false ); + $s4->setIsInline( true ); + + yield [ + <<<INPUT +<languages/> +<translate> +== Unit tests == + +Introduction to unit tests. + +They are fun. +</translate> + +<abbr title="<translate nowrap>Smilie</translate>">:)</abbr> +INPUT + , <<<TRANSLATION_TEMPLATE +<languages/> +<1> + +<2> + +<3> + +<abbr title="<5>">:)</abbr> +TRANSLATION_TEMPLATE + , <<<SOURCE_TEMPLATE +<languages/> +<translate> +<1> + +<2> + +<3> +</translate> + +<abbr title="<translate nowrap><5></translate>">:)</abbr> +SOURCE_TEMPLATE + , + [ + '<1>' => $s1, + '<2>' => $s2, + '<3>' => $s3, + '<5>' => $s4, + ] + ]; + + // Test case 2 // + $s1 = new TranslationUnit(); + $s1->text = '== Unit tests =='; + $s1->id = '11'; + + $s2 = new TranslationUnit(); + $s2->text = 'Introduction to unit tests.'; + $s2->id = '22'; + + $s3 = new TranslationUnit(); + $s3->text = 'They are fun.'; + $s3->id = '33'; + + $s4 = new TranslationUnit(); + $s4->text = 'Smilie'; + $s4->id = '44'; + $s4->setCanWrap( false ); + $s4->setIsInline( true ); + + yield [ + <<<INPUT +<languages/> +<translate> +== Unit tests == <!--T:11--> + +<!--T:22--> +Introduction to unit tests. + +<!--T:33--> +They are fun. +</translate> + +<abbr title="<translate nowrap><!--T:44--> Smilie</translate>">:)</abbr> +INPUT + , <<<TRANSLATION_TEMPLATE +<languages/> +<1> + +<2> + +<3> + +<abbr title="<5>">:)</abbr> +TRANSLATION_TEMPLATE + , <<<SOURCE_TEMPLATE +<languages/> +<translate> +<1> + +<2> + +<3> +</translate> + +<abbr title="<translate nowrap><5></translate>">:)</abbr> +SOURCE_TEMPLATE + , + [ + '<1>' => $s1, + '<2>' => $s2, + '<3>' => $s3, + '<5>' => $s4, + ] + ]; + } + + /** @dataProvider provideTestParseSection */ + public function testParseSection( + string $input, + string $expectedTemplate, + array $expectedUnits, + string $comment + ) { + $parser = new TranslatablePageParser( new TestingParsingPlaceholderFactory() ); + $canWrap = true; + $result = $parser->parseSection( $input, $canWrap ); + $this->assertSame( $expectedTemplate, $result['template'], $comment ); + $this->assertEquals( $expectedUnits, $result['sections'], $comment ); + } + + public static function provideTestParseSection() { + $u = new TranslationUnit(); + $u->text = 'Hello'; + $u->id = -1; + $u->setIsInline( true ); + yield [ + 'Hello', + '<0>', + [ '<0>' => $u ], + 'No surrounding whitespace', + ]; + + $u = new TranslationUnit(); + $u->text = 'Hello'; + $u->id = -1; + yield [ + "\nHello", + "\n<0>", + [ '<0>' => $u ], + 'With surrounding whitespace', + ]; + + $u0 = new TranslationUnit(); + $u0->text = 'Hello world'; + $u0->id = -1; + + $u1 = new TranslationUnit(); + $u1->text = 'Bunny'; + $u1->id = -1; + yield [ + "\nHello world\n\nBunny\n", + "\n<0>\n\n<1>\n", + [ '<0>' => $u0, '<1>' => $u1 ], + 'Splitting at one empty line', + ]; + + $u0 = new TranslationUnit(); + $u0->text = 'First'; + $u0->id = -1; + + $u1 = new TranslationUnit(); + $u1->text = 'Second'; + $u1->id = -1; + + $u2 = new TranslationUnit(); + $u2->text = 'Third'; + $u2->id = -1; + yield [ + "First\n\n\n\n\nSecond\n\nThird", + "<0>\n\n\n\n\n<1>\n\n<2>", + [ '<0>' => $u0, '<1>' => $u1, '<2>' => $u2 ], + 'Splitting with multiple empty lines', + ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslationUnitTest.php b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslationUnitTest.php new file mode 100644 index 00000000..f87860ca --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/PageTranslation/TranslationUnitTest.php @@ -0,0 +1,295 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\PageTranslation; + +use FatMessage; +use Language; +use MediaWikiUnitTestCase; + +/** + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\PageTranslation\TranslationUnit + */ +class TranslationUnitTest extends MediaWikiUnitTestCase { + public function setUp(): void { + parent::setUp(); + + if ( !defined( 'TRANSLATE_FUZZY' ) ) { + define( 'TRANSLATE_FUZZY', '!!FUZZY!!' ); + } + } + + /** @dataProvider providerTestGetMarkedText */ + public function testGetMarkedText( + string $name, string $text, bool $inline, string $expected + ) { + $section = new TranslationUnit(); + $section->name = $name; + $section->text = $text; + $section->setIsInline( $inline ); + + $output = $section->getMarkedText(); + + $this->assertEquals( $expected, $output ); + } + + /** @dataProvider providerTestGetTextWithVariables */ + public function testGetTextWithVariables( string $text, string $expected ) { + $section = new TranslationUnit(); + $section->text = $text; + + $output = $section->getTextWithVariables(); + + $this->assertEquals( $expected, $output ); + } + + /** @dataProvider providerTestGetTextForTrans */ + public function testGetTextForTrans( string $text, string $expected ) { + $section = new TranslationUnit(); + $section->text = $text; + + $output = $section->getTextForTrans(); + + $this->assertEquals( $expected, $output ); + } + + public static function providerTestGetMarkedText() { + $cases = []; + + // Inline syntax + $cases[] = [ + 'name', + 'Hello', + true, + '<!--T:name--> Hello', + ]; + + // Normal syntax + $cases[] = [ + 'name', + 'Hello', + false, + "<!--T:name-->\nHello", + ]; + + // Inline should not matter for headings, which have special syntax, but test both values + $cases[] = [ + 'name', + '== Hello ==', + true, + '== Hello == <!--T:name-->', + ]; + + $cases[] = [ + 'name', + '====== Hello ======', + false, + '====== Hello ====== <!--T:name-->', + ]; + + return $cases; + } + + public static function providerTestGetTextWithVariables() { + $cases = []; + + // syntax + $cases[] = [ + "<tvar|abc>Peter\n cat!</>", + '$abc', + ]; + + $cases[] = [ + "<tvar|1>Hello</>\n<tvar|2>Hello</>", + "$1\n$2", + ]; + + return $cases; + } + + public static function providerTestGetTextForTrans() { + $cases = []; + + // syntax + $cases[] = [ + "<tvar|abc>Peter\n cat!</>", + "Peter\n cat!", + ]; + + $cases[] = [ + "<tvar|1>Hello</>\n<tvar|2>Hello</>", + "Hello\nHello", + ]; + + return $cases; + } + + /** @dataProvider provideTestGetTextForRendering */ + public function testGetTextForRendering( + string $source, + ?string $translation, + bool $fuzzy, + bool $inline, + string $expected + ) { + $unit = new TranslationUnit(); + $unit->text = $source; + $unit->setIsInline( $inline ); + + $msg = null; + if ( $translation !== null ) { + $msg = new FatMessage( '', $unit->getTextWithVariables() ); + $msg->setTranslation( $translation ); + if ( $fuzzy ) { + $msg->addTag( 'fuzzy' ); + } + } + + $sourceLanguage = $this->createStub( Language::class ); + $sourceLanguage->method( 'getHtmlCode' )->willReturn( 'en-GB' ); + $sourceLanguage->method( 'getCode' )->willReturn( 'en-gb' ); + $sourceLanguage->method( 'getDir' )->willReturn( 'ltr' ); + + $targetLanguage = $this->createStub( Language::class ); + $targetLanguage->method( 'getHtmlCode' )->willReturn( 'ar' ); + $targetLanguage->method( 'getCode' )->willReturn( 'ar' ); + $targetLanguage->method( 'getDir' )->willReturn( 'rtl' ); + + $wrapUntranslated = true; + $actual = $unit->getTextForRendering( + $msg, + $sourceLanguage, + $targetLanguage, + $wrapUntranslated + ); + $this->assertEquals( $expected, $actual ); + } + + public function provideTestGetTextForRendering() { + $fuzzy = true; + $inline = true; + $block = false; + + yield 'language wrapping' => [ + 'Hello <tvar|abc>peter</>!', + null, + !$fuzzy, + $inline, + '<span lang="en-GB" dir="ltr" class="mw-content-ltr">Hello peter!</span>' + ]; + + yield 'old translation variable syntax' => [ + 'Hello <tvar|abc>peter</>!', + 'Hejsan $abc!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'translation variable syntax without quotes' => [ + 'Hello <tvar name=abc>peter</tvar>!', + 'Hejsan $abc!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'translation variable syntax with double quotes' => [ + 'Hello <tvar name="abc">peter</tvar>!', + 'Hejsan $abc!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'translation variable syntax with single quotes' => [ + 'Hello <tvar name=\'abc\'>peter</tvar>!', + 'Hejsan $abc!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'translation variable syntax with spaces' => [ + 'Hello <tvar name = abc >peter</tvar>!', + 'Hejsan $abc!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'mixed variable syntax' => [ + 'Hello <tvar name=2>peter</tvar> and <tvar|1>peter</>!', + 'Hejsan $1 and $2!', + !$fuzzy, + $inline, + 'Hejsan peter and peter!' + ]; + + yield 'special characters in variable name' => [ + 'Hello <tvar name=abc_123-АБВ$>peter</tvar>!', + 'Hejsan $abc_123-АБВ$!', + !$fuzzy, + $inline, + 'Hejsan peter!' + ]; + + yield 'inline fuzzy wrapping' => [ + 'Hello <tvar|abc>peter</>!', + 'Hejsan $abc!', + $fuzzy, + $inline, + '<span class="mw-translate-fuzzy">Hejsan peter!</span>' + ]; + + yield 'block language wrapping' => [ + 'Hello <tvar|abc>peter</>!', + null, + !$fuzzy, + $block, + "<div lang=\"en-GB\" dir=\"ltr\" class=\"mw-content-ltr\">\nHello peter!\n</div>" + ]; + + yield 'block variables' => [ + 'Hello <tvar name=abc>peter</tvar>!', + 'Hejsan $abc!', + !$fuzzy, + $block, + 'Hejsan peter!' + ]; + + yield 'block fuzzy wrapping' => [ + 'Hello <tvar|abc>peter</>!', + 'Hejsan $abc!', + $fuzzy, + $block, + "<div class=\"mw-translate-fuzzy\">\nHejsan peter!\n</div>" + ]; + + yield 'translation language in the source' => [ + '{{TRANSLATIONLANGUAGE}}', + null, + !$fuzzy, + $inline, + '<span lang="en-GB" dir="ltr" class="mw-content-ltr">en-gb</span>' + ]; + + yield 'translation language in the translation' => [ + '{{TRANSLATIONLANGUAGE}}', + '{{TRANSLATIONLANGUAGE}}', + $fuzzy, + $inline, + '<span class="mw-translate-fuzzy">ar</span>' + ]; + + yield 'translation language in a variable' => [ + 'Lang: <tvar|code>{{TRANSLATIONLANGUAGE}}</>', + 'Lang: $code', + !$fuzzy, + $inline, + 'Lang: ar' + ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/unit/Statistics/TranslatorActivityTest.php b/MLEB/Translate/tests/phpunit/unit/Statistics/TranslatorActivityTest.php index 3c00fe15..48602904 100644 --- a/MLEB/Translate/tests/phpunit/unit/Statistics/TranslatorActivityTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Statistics/TranslatorActivityTest.php @@ -1,30 +1,29 @@ <?php -/** - * @file - * @author Niklas Laxström - * @license GPL-2.0-or-later - */ +declare( strict_types = 1 ); -namespace MediaWiki\Extensions\Translate\Statistics; +namespace MediaWiki\Extension\Translate\Statistics; use EmptyBagOStuff; use HashBagOStuff; use InvalidArgumentException; use JobQueueGroup; +use MediaWiki\Languages\LanguageNameUtils; use MediaWikiUnitTestCase; use Wikimedia\Timestamp\ConvertibleTimestamp; /** - * @covers \MediaWiki\Extensions\Translate\Statistics\TranslatorActivity + * @author Niklas Laxström + * @license GPL-2.0-or-later + * @covers \MediaWiki\Extension\Translate\Statistics\TranslatorActivity */ class TranslatorActivityTest extends MediaWikiUnitTestCase { public function testInvalidLanguage() { $cache = $this->createMock( EmptyBagOStuff::class ); $query = $this->createMock( TranslatorActivityQuery::class ); $jobQueue = $this->createMock( JobQueueGroup::class ); - $languageValidator = function ( string $language ): bool { - return false; - }; + $languageValidator = $this->createMock( LanguageNameUtils::class ); + $languageValidator->method( 'isKnownLanguageTag' )->willReturn( false ); + $service = new TranslatorActivity( $cache, $query, $jobQueue, $languageValidator ); $this->expectException( InvalidArgumentException::class ); @@ -51,9 +50,9 @@ class TranslatorActivityTest extends MediaWikiUnitTestCase { ->with( $this->equalTo( $language ) ); $jobQueue = $this->createMock( JobQueueGroup::class ); $jobQueue->expects( $this->never() )->method( 'push' ); - $languageValidator = function ( string $language ): bool { - return true; - }; + $languageValidator = $this->createMock( LanguageNameUtils::class ); + $languageValidator->method( 'isKnownLanguageTag' )->willReturn( true ); + $service = new TranslatorActivity( $cache, $query, $jobQueue, $languageValidator ); ConvertibleTimestamp::setFakeTime( $fakeTime1 ); @@ -80,9 +79,9 @@ class TranslatorActivityTest extends MediaWikiUnitTestCase { ->with( $this->equalTo( $language ) ); $jobQueue = $this->createMock( JobQueueGroup::class ); $jobQueue->expects( $this->once() )->method( 'push' ); - $languageValidator = function ( string $language ): bool { - return true; - }; + $languageValidator = $this->createMock( LanguageNameUtils::class ); + $languageValidator->method( 'isKnownLanguageTag' )->willReturn( true ); + $service = new TranslatorActivity( $cache, $query, $jobQueue, $languageValidator ); ConvertibleTimestamp::setFakeTime( $fakeTime1 ); @@ -114,9 +113,9 @@ class TranslatorActivityTest extends MediaWikiUnitTestCase { ->with( $this->equalTo( $language ) ); $jobQueue = $this->createMock( JobQueueGroup::class ); $jobQueue->expects( $this->never() )->method( 'push' ); - $languageValidator = function ( string $language ): bool { - return true; - }; + $languageValidator = $this->createMock( LanguageNameUtils::class ); + $languageValidator->method( 'isKnownLanguageTag' )->willReturn( true ); + $service = new TranslatorActivity( $cache, $query, $jobQueue, $languageValidator ); ConvertibleTimestamp::setFakeTime( $fakeTime1 ); @@ -132,11 +131,13 @@ class TranslatorActivityTest extends MediaWikiUnitTestCase { private function getExampleData(): array { $translators = [ - 'Hunter' => [ + [ + TranslatorActivityQuery::USER_NAME => 'Hunter', TranslatorActivityQuery::USER_TRANSLATIONS => 1234, TranslatorActivityQuery::USER_LAST_ACTIVITY => 10, ], - 'Farmer' => [ + [ + TranslatorActivityQuery::USER_NAME => 'Farmer', TranslatorActivityQuery::USER_TRANSLATIONS => 2, TranslatorActivityQuery::USER_LAST_ACTIVITY => 20, ], diff --git a/MLEB/Translate/tests/phpunit/unit/Synchronization/GroupSynchronizationCacheTest.php b/MLEB/Translate/tests/phpunit/unit/Synchronization/GroupSynchronizationCacheTest.php deleted file mode 100644 index 8a612ee1..00000000 --- a/MLEB/Translate/tests/phpunit/unit/Synchronization/GroupSynchronizationCacheTest.php +++ /dev/null @@ -1,193 +0,0 @@ -<?php - -namespace MediaWiki\Extensions\Translate\Synchronization; - -use HashBagOStuff; -use MediaWikiUnitTestCase; - -/** - * @covers \MediaWiki\Extensions\Translate\Synchronization\GroupSynchronizationCache - * @covers \MediaWiki\Extensions\Translate\Synchronization\GroupSynchronizationResponse - */ -class GroupSynchronizationCacheTest extends MediaWikiUnitTestCase { - /** @var GroupSynchronizationCache */ - private $groupSyncCache; - - protected function setUp(): void { - $this->groupSyncCache = $this->getGroupSynchronizationCache(); - } - - public function testIsGroupBeingProcessed() { - $groupId = 'hello'; - $this->groupSyncCache->startSync( $groupId ); - - $this->assertTrue( $this->groupSyncCache->isGroupBeingProcessed( $groupId ) ); - - $this->groupSyncCache->endSync( $groupId ); - - $this->assertFalse( $this->groupSyncCache->isGroupBeingProcessed( $groupId ) ); - } - - public function testGetGroupMessageKeys() { - $groupId = 'hello'; - $title = 'Title'; - - $this->groupSyncCache->startSync( $groupId ); - $this->groupSyncCache->addMessages( - $groupId, - $this->getMessageParam( $groupId, $title ) - ); - - $this->assertEquals( - [ $title ], $this->groupSyncCache->getGroupMessageKeys( $groupId ) - ); - - $this->groupSyncCache->removeMessages( $title ); - - $this->assertEquals( - [ $title ], - $this->groupSyncCache->getGroupMessageKeys( $groupId ), - 'Removing a message does not update the group message list.' - ); - } - - public function testGetGroupsInSync() { - $groupId = 'hello'; - - $this->groupSyncCache->startSync( $groupId ); - $this->assertEquals( [ $groupId ], $this->groupSyncCache->getGroupsInSync() ); - - $this->groupSyncCache->endSync( $groupId ); - $this->assertEquals( [], $this->groupSyncCache->getGroupsInSync() ); - } - - public function testEndSync() { - $groupId = 'group-id'; - $title = 'hello'; - - $this->groupSyncCache->startSync( $groupId ); - $this->groupSyncCache->addMessages( - $groupId, $this->getMessageParam( $groupId, $title ) - ); - $this->assertNotEmpty( $this->groupSyncCache->getMessages( $title )[$title] ); - $this->assertTrue( $this->groupSyncCache->isGroupBeingProcessed( $groupId ) ); - - $this->groupSyncCache->endSync( $groupId ); - - $message = $this->groupSyncCache->getMessages( $title )[$title]; - $this->assertEmpty( $message ); - } - - /** - * @dataProvider provideGetSynchronizationStatus - */ - public function testGetSynchronizationStatus( - GroupSynchronizationCache $syncCache, - string $groupId, - array $titlesToAdd, - array $titlesToRemove, - bool $hasTimedOut = false - ) { - $syncCache->startSync( $groupId ); - - $this->assertTrue( $syncCache->isGroupBeingProcessed( $groupId ) ); - - foreach ( $titlesToAdd as $title ) { - $syncCache->addMessages( - $groupId, $this->getMessageParam( $groupId, $title ) - ); - } - - $this->assertEquals( $titlesToAdd, $syncCache->getGroupMessageKeys( $groupId ) ); - - $syncCache->removeMessages( ...$titlesToRemove ); - - $groupSyncResponse = $syncCache->getSynchronizationStatus( $groupId ); - - $diffArray = array_values( array_diff( $titlesToAdd, $titlesToRemove ) ); - $this->assertEquals( $diffArray, $syncCache->getGroupMessageKeys( $groupId ) ); - - if ( $diffArray === [] ) { - $this->assertEmpty( $this->groupSyncCache->getGroupsInSync() ); - } - - $this->assertEquals( $diffArray === [], $groupSyncResponse->isDone() ); - $this->assertEquals( $hasTimedOut, $groupSyncResponse->hasTimedOut() ); - $this->assertEquals( - $diffArray, - $groupSyncResponse->getRemainingMessages() - ); - $this->assertEquals( $groupId, $groupSyncResponse->getGroupId() ); - } - - public function testGetMulti() { - $groupId = 'hello'; - - $this->groupSyncCache->addMessages( $groupId, - $this->getMessageParam( $groupId, 'Title' ), - $this->getMessageParam( $groupId, 'Title_ABC' ) - ); - - $messages = $this->groupSyncCache->getMessages( 'Title', 'Title_ABC', 'Title_ABCD' ); - $this->assertEquals( [ 'Title', 'Title_ABC', 'Title_ABCD' ], array_keys( $messages ) ); - - $messages = $this->groupSyncCache->getMessages( 'Title_ABCD' ); - $this->assertNull( $messages['Title_ABCD'] ); - } - - public function provideGetSynchronizationStatus() { - $groupId = 'hello'; - $syncCache = $this->getGroupSynchronizationCache(); - yield [ - $syncCache, - $groupId, - [ 'Title', 'Title1' ], - [ 'Title' ], - false - ]; - - $syncCache = $this->getGroupSynchronizationCache(); - yield [ - $syncCache, - $groupId, - [ 'Hello' ], - [ 'Hello' ], - false - ]; - - $syncCache = $this->getGroupSynchronizationCache( -1 ); - yield [ - $syncCache, - $groupId, - [ 'Hello' ], - [ 'Hello' ], - false - ]; - - $syncCache = $this->getGroupSynchronizationCache( -1 ); - yield [ - $syncCache, - $groupId, - [ 'Hello', 'Title' ], - [ 'Hello' ], - true - ]; - } - - private function getMessageParam( string $groupId, string $title ): MessageUpdateParameter { - return new MessageUpdateParameter( [ - 'fuzzy' => true, - 'content' => 'Hello', - 'title' => $title, - 'groupId' => $groupId - ] ); - } - - private function getGroupSynchronizationCache( int $timeout = null ): GroupSynchronizationCache { - if ( $timeout ) { - return new GroupSynchronizationCache( new HashBagOStuff(), $timeout ); - } - - return new GroupSynchronizationCache( new HashBagOStuff() ); - } -} diff --git a/MLEB/Translate/tests/phpunit/unit/Synchronization/MessageUpdateParameterTest.php b/MLEB/Translate/tests/phpunit/unit/Synchronization/MessageUpdateParameterTest.php index 22e4f639..1f901b97 100644 --- a/MLEB/Translate/tests/phpunit/unit/Synchronization/MessageUpdateParameterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Synchronization/MessageUpdateParameterTest.php @@ -1,18 +1,14 @@ <?php -namespace MediaWiki\Extensions\Translate\Synchronization; +namespace MediaWiki\Extension\Translate\Synchronization; use MediaWikiUnitTestCase; use MessageUpdateJob; use Title; -/** - * @covers \MediaWiki\Extensions\Translate\Synchronization\MessageUpdateParameter - */ +/** @covers \MediaWiki\Extension\Translate\Synchronization\MessageUpdateParameter */ class MessageUpdateParameterTest extends MediaWikiUnitTestCase { - /** - * @dataProvider provideSerializable - */ + /** @dataProvider provideSerializable */ public function testSerializable( string $title, string $content, @@ -32,9 +28,7 @@ class MessageUpdateParameterTest extends MediaWikiUnitTestCase { $this->assertEquals( $messageParam, $serializedMessageParam ); } - /** - * @dataProvider provideSerializable - */ + /** @dataProvider provideSerializable */ public function testCreateFromJob( string $title, string $content, @@ -52,10 +46,13 @@ class MessageUpdateParameterTest extends MediaWikiUnitTestCase { $this->assertEquals( $content, $messageParams->getContent() ); $this->assertEquals( $isRename, $messageParams->isRename() ); $this->assertEquals( $isFuzzy, $messageParams->isFuzzy() ); + if ( $isRename ) { $this->assertEquals( $target, $messageParams->getTargetValue() ); $this->assertEquals( $replacement, $messageParams->getReplacementValue() ); $this->assertEquals( $otherLangs, $messageParams->getOtherLangs() ); + } else { + $this->assertNull( $messageParams->getOtherLangs() ); } } diff --git a/MLEB/Translate/tests/phpunit/insertables/CombinedInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/CombinedInsertablesSuggesterTest.php index bc0b5b2e..1f2d82b1 100644 --- a/MLEB/Translate/tests/phpunit/insertables/CombinedInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/CombinedInsertablesSuggesterTest.php @@ -1,15 +1,17 @@ <?php - /** * @file * @author Geoffrey Mon * @license GPL-2.0-or-later */ -class CombinedInsertablesSuggesterTest extends MediaWikiIntegrationTestCase { - /** - * @dataProvider getInsertablesProvider - */ +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; + +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\CombinedInsertablesSuggester */ +class CombinedInsertablesSuggesterTest extends MediaWikiUnitTestCase { + /** @dataProvider getInsertablesProvider */ public function testGetInsertables( $suggesters, $input, $expected ) { $suggester = new CombinedInsertablesSuggester( $suggesters ); $this->assertArrayEquals( $expected, $suggester->getInsertables( $input ) ); @@ -70,13 +72,13 @@ class CombinedInsertablesSuggesterTest extends MediaWikiIntegrationTestCase { } class TestingInsertablesSuggester implements InsertablesSuggester { - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( 'Test', 'Test', '' ) ]; } } class TestingDuplicateInsertablesSuggester implements InsertablesSuggester { - public function getInsertables( $text ) { + public function getInsertables( string $text ): array { return [ new Insertable( '$1', '$1', '' ), new Insertable( '$1', '$1', '' ), diff --git a/MLEB/Translate/tests/phpunit/unit/insertables/HtmlTagInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/HtmlTagInsertablesSuggesterTest.php index ebd1ee8f..fd439254 100644 --- a/MLEB/Translate/tests/phpunit/unit/insertables/HtmlTagInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/HtmlTagInsertablesSuggesterTest.php @@ -5,13 +5,13 @@ * @license GPL-2.0-or-later */ -/** - * @covers HtmlTagInsertablesSuggester - */ +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; + +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\HtmlTagInsertablesSuggester */ class HtmlTagInsertablesSuggesterTest extends MediaWikiUnitTestCase { - /** - * @dataProvider getTestHtmlTagInsertablesSuggesterProvider - */ + /** @dataProvider getTestHtmlTagInsertablesSuggesterProvider */ public function testHtmlTagInsertablesSuggester( $text, $expected, $comment = '' ) { $suggester = new HtmlTagInsertablesSuggester(); $actual = $suggester->getInsertables( $text ); diff --git a/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/InsertableFactoryTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/InsertableFactoryTest.php new file mode 100644 index 00000000..7b20fa12 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/InsertableFactoryTest.php @@ -0,0 +1,56 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; + +use InvalidArgumentException; +use MediaWikiUnitTestCase; +use MockTranslateValidator; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\InsertableFactory */ +class InsertableFactoryTest extends MediaWikiUnitTestCase { + /** + * @dataProvider getPreProvidedInsertables + * @dataProvider getCustomInsertables + */ + public function testValidLoadInstance( string $className, $params = null ) { + $instance = InsertableFactory::make( $className, $params ); + $this->assertInstanceOf( + InsertablesSuggester::class, + $instance, + 'Existing class returns an instance of the InsertableSuggester' + ); + } + + public function testNonExistentInsertable() { + $this->expectException( InvalidArgumentException::class ); + $this->expectExceptionMessageMatches( '/could not find/i' ); + InsertableFactory::make( 'TranslateNonExistentClass', '' ); + } + + public function testInvalidInsertable() { + $this->expectException( InvalidArgumentException::class ); + $this->expectExceptionMessageMatches( '/does not implement/i' ); + InsertableFactory::make( MockTranslateValidator::class, '' ); + } + + public function getPreprovidedInsertables() { + yield [ HtmlTagInsertablesSuggester::class ]; + + yield [ + RegexInsertablesSuggester::class, + [ 'regex' => 'abcd' ] + ]; + + yield [ RegexInsertablesSuggester::class, 'abcd' ]; + + yield 'Preprovided insertables without fully qualified namespace' => [ + // Not using ::class since that would add the fully qualified namespace + 'NumericalParameterInsertablesSuggester' + ]; + } + + public function getCustomInsertables() { + yield [ \MockCustomInsertableSuggester::class ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/insertables/MediaWikiInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/MediaWikiInsertablesSuggesterTest.php index d49206f7..a8e419c3 100644 --- a/MLEB/Translate/tests/phpunit/insertables/MediaWikiInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/MediaWikiInsertablesSuggesterTest.php @@ -5,11 +5,13 @@ * @license GPL-2.0-or-later */ -class MediaWikiInsertablesSuggesterTest extends PHPUnit\Framework\TestCase { +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; - /** - * @dataProvider getInsertablesProvider - */ +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\MediaWikiInsertablesSuggester */ +class MediaWikiInsertablesSuggesterTest extends MediaWikiUnitTestCase { + /** @dataProvider getInsertablesProvider */ public function testGetInsertables( $input, $expected ) { $suggester = new MediaWikiInsertablesSuggester(); $this->assertEquals( $expected, $suggester->getInsertables( $input ) ); diff --git a/MLEB/Translate/tests/phpunit/insertables/NumericalParameterInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/NumericalParameterInsertablesSuggesterTest.php index d2a8f4b6..a8913585 100644 --- a/MLEB/Translate/tests/phpunit/insertables/NumericalParameterInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/NumericalParameterInsertablesSuggesterTest.php @@ -1,17 +1,19 @@ <?php - /** * @file * @author Geoffrey Mon * @license GPL-2.0-or-later */ -class NumericalParameterInsertablesSuggesterTest extends PHPUnit\Framework\TestCase { - /** - * @dataProvider getInsertablesProvider - */ +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; + +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\NumericalParameterInsertablesSuggester */ +class NumericalParameterInsertablesSuggesterTest extends MediaWikiUnitTestCase { + /** @dataProvider getInsertablesProvider */ public function testGetInsertables( $input, $expected ) { - $suggester = new MediaWikiInsertablesSuggester(); + $suggester = new NumericalParameterInsertablesSuggester(); $this->assertEquals( $expected, $suggester->getInsertables( $input ) ); } diff --git a/MLEB/Translate/tests/phpunit/insertables/RegexInsertablesSuggesterTest.php b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/RegexInsertablesSuggesterTest.php index 86b7f6e5..e17be4fd 100644 --- a/MLEB/Translate/tests/phpunit/insertables/RegexInsertablesSuggesterTest.php +++ b/MLEB/Translate/tests/phpunit/unit/TranslatorInterface/Insertable/RegexInsertablesSuggesterTest.php @@ -5,10 +5,13 @@ * @license GPL-2.0-or-later */ -class RegexInsertablesSuggesterTest extends PHPUnit\Framework\TestCase { - /** - * @dataProvider getTestRegexInsertableProvider - */ +namespace MediaWiki\Extension\Translate\TranslatorInterface\Insertable; + +use MediaWikiUnitTestCase; + +/** @covers \MediaWiki\Extension\Translate\TranslatorInterface\Insertable\RegexInsertablesSuggester */ +class RegexInsertablesSuggesterTest extends MediaWikiUnitTestCase { + /** @dataProvider getTestRegexInsertableProvider */ public function testRegexInsertable( $text, $params, $expectedVals ) { $insertablesSuggester = new RegexInsertablesSuggester( $params ); $insertables = $insertablesSuggester->getInsertables( $text ); diff --git a/MLEB/Translate/tests/phpunit/unit/TtmServer/TtmServerFactoryTest.php b/MLEB/Translate/tests/phpunit/unit/TtmServer/TtmServerFactoryTest.php new file mode 100644 index 00000000..4bcdf8e4 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/TtmServer/TtmServerFactoryTest.php @@ -0,0 +1,59 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\TtmServer; + +use DatabaseTTMServer; +use MediaWikiUnitTestCase; + +/** + * @since 2021.01 + * @license GPL-2.0-or-later + * @author Niklas Laxström + * @covers \MediaWiki\Extension\Translate\TtmServer\TtmServerFactory + */ +class TtmServerFactoryTest extends MediaWikiUnitTestCase { + public function testGetNames() { + $factory = new TtmServerFactory( [ 'one' => [], 'two' => [] ] ); + $actual = $factory->getNames(); + $this->assertArrayEquals( [ 'one', 'two' ], $actual ); + } + + public function testHas() { + $factory = new TtmServerFactory( [ 'exists' => [] ], 'exists' ); + $this->assertFalse( $factory->has( 'unknown' ) ); + $this->assertTrue( $factory->has( 'exists' ) ); + } + + public function testCreate() { + $name = '1'; + $factory = new TtmServerFactory( + [ + $name => [ + 'database' => false, + // Passed to wfGetDB + 'cutoff' => 0.75, + 'type' => 'ttmserver', + 'public' => false, + ], + ], + $name + ); + + $actual = $factory->create( $name ); + $this->assertInstanceOf( DatabaseTTMServer::class, $actual ); + } + + /** @dataProvider provideCreateFailure */ + public function testCreateFailure( array $input ) { + $factory = new TtmServerFactory( $input ); + $this->expectException( ServiceCreationFailure::class ); + $factory->create( '' ); + } + + public function provideCreateFailure() { + yield 'unknown' => [ [] ]; + yield 'malformed' => [ [ '' => 'gibberish' ] ]; + yield 'incomplete config' => [ [ '' => [ 'someoption' => 'somevalue' ] ] ]; + } +} diff --git a/MLEB/Translate/tests/phpunit/unit/Utilities/GettextPluralTest.php b/MLEB/Translate/tests/phpunit/unit/Utilities/GettextPluralTest.php index b2e1db28..bf4f727e 100644 --- a/MLEB/Translate/tests/phpunit/unit/Utilities/GettextPluralTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Utilities/GettextPluralTest.php @@ -4,15 +4,11 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\Utilities\GettextPlural; +use MediaWiki\Extension\Translate\Utilities\GettextPlural; -/** - * @coversDefaultClass \MediaWiki\Extensions\Translate\Utilities\GettextPlural - */ +/** @coversDefaultClass \MediaWiki\Extension\Translate\Utilities\GettextPlural */ class GettextPluralTest extends MediaWikiUnitTestCase { - /** - * @covers ::getPluralRule - */ + /** @covers ::getPluralRule */ public function testGetPluralRule() { $expected = 'nplurals=2; plural=(n != 1);'; $actual = GettextPlural::getPluralRule( 'en' ); diff --git a/MLEB/Translate/tests/phpunit/unit/Utilities/JsonCodecTest.php b/MLEB/Translate/tests/phpunit/unit/Utilities/JsonCodecTest.php new file mode 100644 index 00000000..9dc60874 --- /dev/null +++ b/MLEB/Translate/tests/phpunit/unit/Utilities/JsonCodecTest.php @@ -0,0 +1,129 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\Utilities\Json; + +use InvalidArgumentException; +use JsonSerializable; +use MediaWikiUnitTestCase; +use MockJsonUnserializableSubClass; +use MockJsonUnserializableSuperClass; +use stdClass; +use Wikimedia\Assert\PreconditionException; + +/** + * Remove once we need to support only MW >= 1.36 + * See Change-Id: I5433090ae8e2b3f2a4590cc404baf838025546ce + * + * @covers \MediaWiki\Extension\Translate\Utilities\Json\JsonCodec + * @covers \MediaWiki\Extension\Translate\Utilities\Json\JsonUnserializableTrait + */ +class JsonCodecTest extends MediaWikiUnitTestCase { + + private function getCodec(): JsonCodec { + return new JsonCodec(); + } + + public function provideSimpleTypes() { + yield 'Integer' => [ 1, json_encode( 1 ) ]; + yield 'Boolean' => [ true, json_encode( true ) ]; + yield 'Null' => [ null, json_encode( null ) ]; + yield 'Array' => [ [ 1, 2, 3 ], json_encode( [ 1, 2, 3 ] ) ]; + yield 'Assoc array' => [ [ 'a' => 'b' ], json_encode( [ 'a' => 'b' ] ) ]; + $object = new stdClass(); + $object->c = 'd'; + yield 'Object' => [ (array)$object, json_encode( $object ) ]; + } + + /** + * @dataProvider provideSimpleTypes + * @param mixed $value + */ + public function testSimpleTypesUnserialize( $value, string $serialization ) { + $this->assertSame( $value, $this->getCodec()->unserialize( $serialization ) ); + } + + public function testInvalidJsonDataForClassExpectation() { + $this->expectException( InvalidArgumentException::class ); + $this->getCodec()->unserialize( 'bad string', MockJsonUnserializableSuperClass::class ); + } + + public function testExpectedClassMustBeUnserializable() { + $this->expectException( PreconditionException::class ); + $this->getCodec()->unserialize( '{}', self::class ); + } + + public function testUnexpectedClassUnserialized() { + $this->expectException( InvalidArgumentException::class ); + $superClassInstance = new MockJsonUnserializableSuperClass( 'Godzilla' ); + $this->getCodec()->unserialize( + $superClassInstance->jsonSerialize(), + MockJsonUnserializableSubClass::class + ); + } + + public function testExpectedClassUnserialized() { + $subClassInstance = new MockJsonUnserializableSubClass( 'Godzilla', 'But we are ready!' ); + $this->assertNotNull( $this->getCodec()->unserialize( + $subClassInstance->jsonSerialize(), + MockJsonUnserializableSuperClass::class + ) ); + $this->assertNotNull( $this->getCodec()->unserialize( + $subClassInstance->jsonSerialize(), + MockJsonUnserializableSubClass::class + ) ); + } + + public function testRoundTripSuperClass() { + $superClassInstance = new MockJsonUnserializableSuperClass( 'Super Value' ); + $json = $superClassInstance->jsonSerialize(); + $superClassUnserialized = $this->getCodec()->unserialize( $json ); + $this->assertInstanceOf( MockJsonUnserializableSuperClass::class, $superClassInstance ); + $this->assertSame( $superClassInstance->getSuperClassField(), $superClassUnserialized->getSuperClassField() ); + } + + public function testRoundTripSubClass() { + $subClassInstance = new MockJsonUnserializableSubClass( 'Super Value', 'Sub Value' ); + $json = $subClassInstance->jsonSerialize(); + $superClassUnserialized = $this->getCodec()->unserialize( $json ); + $this->assertInstanceOf( MockJsonUnserializableSubClass::class, $subClassInstance ); + $this->assertSame( $subClassInstance->getSuperClassField(), $superClassUnserialized->getSuperClassField() ); + $this->assertSame( $subClassInstance->getSubClassField(), $superClassUnserialized->getSubClassField() ); + } + + public function provideSerializeThrowsOnFailure() { + yield 'crash in serialization, gzipped data' => [ + "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xcb\x48\xcd\xc9\xc9\x57\x28\xcf\x2f' + . '\xca\x49\x01\x00\x85\x11\x4a\x0d\x0b\x00\x00\x00" + ]; + } + + /** + * @dataProvider provideSerializeThrowsOnFailure + * @covers \MediaWiki\Extension\Translate\Utilities\Json\JsonCodec::serialize + * @param mixed $value + */ + public function testSerializeThrowsOnFailure( $value ) { + $this->expectException( InvalidArgumentException::class ); + $this->getCodec()->serialize( $value ); + } + + public function provideSerializeSuccess() { + $serializableInstance = new class() implements JsonSerializable { + public function jsonSerialize() { + return json_encode( [ 'c' => 'd' ] ); + } + }; + yield 'array' => [ [ 'a' => 'b' ], '{"a":"b"}' ]; + yield 'JsonSerializable' => [ $serializableInstance, '{"c":"d"}' ]; + } + + /** + * @dataProvider provideSerializeSuccess + * @covers \MediaWiki\Extension\Translate\Utilities\Json\JsonCodec::serialize + * @param mixed $value + */ + public function testSerializeSuccess( $value, string $expected ) { + $this->assertSame( $expected, $this->getCodec()->serialize( $value ) ); + } +} diff --git a/MLEB/Translate/tests/phpunit/unit/Utilities/ParsingPlaceholderFactoryTest.php b/MLEB/Translate/tests/phpunit/unit/Utilities/ParsingPlaceholderFactoryTest.php index 9fd16330..76a719b0 100644 --- a/MLEB/Translate/tests/phpunit/unit/Utilities/ParsingPlaceholderFactoryTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Utilities/ParsingPlaceholderFactoryTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\Utilities\ParsingPlaceholderFactory; +use MediaWiki\Extension\Translate\Utilities\ParsingPlaceholderFactory; /** * @author Niklas Laxström * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\Utilities\ParsingPlaceholderFactory + * @covers \MediaWiki\Extension\Translate\Utilities\ParsingPlaceholderFactory */ class ParsingPlaceholderFactoryTest extends MediaWikiUnitTestCase { public function testMake() { diff --git a/MLEB/Translate/tests/phpunit/unit/Utilities/SmartFormatPluralTest.php b/MLEB/Translate/tests/phpunit/unit/Utilities/SmartFormatPluralTest.php index 488279a5..9ed3a8ed 100644 --- a/MLEB/Translate/tests/phpunit/unit/Utilities/SmartFormatPluralTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Utilities/SmartFormatPluralTest.php @@ -4,15 +4,11 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\Utilities\SmartFormatPlural; +use MediaWiki\Extension\Translate\Utilities\SmartFormatPlural; -/** - * @covers \MediaWiki\Extensions\Translate\Utilities\SmartFormatPlural - */ +/** @covers \MediaWiki\Extension\Translate\Utilities\SmartFormatPlural */ class SmartFormatPluralTest extends MediaWikiUnitTestCase { - /** - * @dataProvider provideTestGetPluralInstances - */ + /** @dataProvider provideTestGetPluralInstances */ public function testGetPluralInstances( $input, $expected ) { $actual = SmartFormatPlural::getPluralInstances( $input ); $this->assertEquals( $expected, $actual ); diff --git a/MLEB/Translate/tests/phpunit/unit/Utilities/UnicodePluralTest.php b/MLEB/Translate/tests/phpunit/unit/Utilities/UnicodePluralTest.php index a98af4fe..a7f4498d 100644 --- a/MLEB/Translate/tests/phpunit/unit/Utilities/UnicodePluralTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Utilities/UnicodePluralTest.php @@ -4,15 +4,11 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\Utilities\UnicodePlural; +use MediaWiki\Extension\Translate\Utilities\UnicodePlural; -/** - * @coversDefaultClass \MediaWiki\Extensions\Translate\Utilities\UnicodePlural - */ +/** @coversDefaultClass \MediaWiki\Extension\Translate\Utilities\UnicodePlural */ class UnicodePluralTest extends MediaWikiUnitTestCase { - /** - * @covers ::getPluralKeywords - */ + /** @covers ::getPluralKeywords */ public function testGetPluralKeywords() { $expected = [ 'one', 'other' ]; $actual = UnicodePlural::getPluralKeywords( 'en' ); diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/BaseValidatorTestCase.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/BaseValidatorTestCase.php index 9932ffc2..46d8ec60 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/BaseValidatorTestCase.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/BaseValidatorTestCase.php @@ -1,11 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\Validation\MessageValidator; -use MediaWiki\Extensions\Translate\Validation\ValidationIssue; -use MediaWiki\Extensions\Translate\Validation\ValidationIssues; +use MediaWiki\Extension\Translate\Validation\MessageValidator; +use MediaWiki\Extension\Translate\Validation\ValidationIssue; +use MediaWiki\Extension\Translate\Validation\ValidationIssues; /** + * Base class for translation validator tests * @license GPL-2.0-or-later */ class BaseValidatorTestCase extends MediaWikiUnitTestCase { diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/BraceBalanceValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/BraceBalanceValidatorTest.php index 477ff075..2e0f6dcc 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/BraceBalanceValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/BraceBalanceValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\BraceBalanceValidator; +use MediaWiki\Extension\Translate\Validation\Validators\BraceBalanceValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\BraceBalanceValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\BraceBalanceValidator */ class BraceBalanceValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/EscapeCharacterValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/EscapeCharacterValidatorTest.php index 25661253..f1744827 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/EscapeCharacterValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/EscapeCharacterValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\EscapeCharacterValidator; +use MediaWiki\Extension\Translate\Validation\Validators\EscapeCharacterValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\EscapeCharacterValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\EscapeCharacterValidator */ class EscapeCharacterValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/GettextNewlineValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/GettextNewlineValidatorTest.php index 3dade6a3..e2828f1b 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/GettextNewlineValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/GettextNewlineValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\GettextNewlineValidator; +use MediaWiki\Extension\Translate\Validation\Validators\GettextNewlineValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\GettextNewlineValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\GettextNewlineValidator */ class GettextNewlineValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/GettextPluralValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/GettextPluralValidatorTest.php index da81da39..a3e6dc83 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/GettextPluralValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/GettextPluralValidatorTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\GettextPluralValidator; +use MediaWiki\Extension\Translate\Validation\Validators\GettextPluralValidator; /** * @author Niklas Laxström * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\GettextPluralValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\GettextPluralValidator */ class GettextPluralValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/InsertableRegexValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/InsertableRegexValidatorTest.php index 219379ee..dc008579 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/InsertableRegexValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/InsertableRegexValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\InsertableRegexValidator; +use MediaWiki\Extension\Translate\Validation\Validators\InsertableRegexValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\InsertableRegexValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\InsertableRegexValidator */ class InsertableRegexValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/InsertableRubyVariableValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/InsertableRubyVariableValidatorTest.php index 3b4c3e3b..af67dfac 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/InsertableRubyVariableValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/InsertableRubyVariableValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\InsertableRubyVariableValidator; +use MediaWiki\Extension\Translate\Validation\Validators\InsertableRubyVariableValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\InsertableRubyVariableValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\InsertableRubyVariableValidator */ class InsertableRubyValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/IosVariableValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/IosVariableValidatorTest.php index 9a2de037..e7a0e1db 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/IosVariableValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/IosVariableValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\IosVariableValidator; +use MediaWiki\Extension\Translate\Validation\Validators\IosVariableValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\IosVariableValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\IosVariableValidator */ class IosVariableValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MatchSetValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MatchSetValidatorTest.php index 3c0ebcd8..9ca10165 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MatchSetValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MatchSetValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MatchSetValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MatchSetValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MatchSetValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MatchSetValidator */ class MatchSetValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiLinkValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiLinkValidatorTest.php index 2cbf17c0..eaaa1155 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiLinkValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiLinkValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiLinkValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MediaWikiLinkValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiLinkValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MediaWikiLinkValidator */ class MediaWikiLinkValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiPageNameValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiPageNameValidatorTest.php index a024b398..fbc47ed5 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiPageNameValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiPageNameValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiPageNameValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MediaWikiPageNameValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiPageNameValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MediaWikiPageNameValidator */ class MediaWikiPageNameValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiParameterValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiParameterValidatorTest.php index 2e824779..f2ba8d86 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiParameterValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiParameterValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiParameterValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MediaWikiParameterValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiParameterValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MediaWikiParameterValidator */ class MediaWikiParameterValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiTimeListValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiTimeListValidatorTest.php index 98097733..127274c7 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/MediaWikiTimeListValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/MediaWikiTimeListValidatorTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiTimeListValidator; +use MediaWiki\Extension\Translate\Validation\Validators\MediaWikiTimeListValidator; /** * @author Niklas Laxström * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\MediaWikiTimeListValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\MediaWikiTimeListValidator */ class MediaWikiTimeListValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/NewlineValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/NewlineValidatorTest.php index 14853688..6e310f50 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/NewlineValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/NewlineValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\NewlineValidator; +use MediaWiki\Extension\Translate\Validation\Validators\NewlineValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\NewlineValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\NewlineValidator */ class NewlineValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/NumericalParameterValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/NumericalParameterValidatorTest.php index 5d900b4f..c4665c8c 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/NumericalParameterValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/NumericalParameterValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\NumericalParameterValidator; +use MediaWiki\Extension\Translate\Validation\Validators\NumericalParameterValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\NumericalParameterValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\NumericalParameterValidator */ class NumericalParameterValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/PrintfValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/PrintfValidatorTest.php index 6ea13a10..666d7bfd 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/PrintfValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/PrintfValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\PrintfValidator; +use MediaWiki\Extension\Translate\Validation\Validators\PrintfValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\PrintfValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\PrintfValidator */ class PrintfValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/PythonInterpolationValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/PythonInterpolationValidatorTest.php index 709adb8f..456b2b51 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/PythonInterpolationValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/PythonInterpolationValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\PythonInterpolationValidator; +use MediaWiki\Extension\Translate\Validation\Validators\PythonInterpolationValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\PythonInterpolationValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\PythonInterpolationValidator */ class PythonInterpolationValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/ReplacementValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/ReplacementValidatorTest.php index 44c2a5e7..31cf88a1 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/ReplacementValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/ReplacementValidatorTest.php @@ -1,12 +1,12 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\ReplacementValidator; +use MediaWiki\Extension\Translate\Validation\Validators\ReplacementValidator; /** * @author Niklas Laxström * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\ReplacementValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\ReplacementValidator */ class ReplacementValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/SmartFormatPluralValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/SmartFormatPluralValidatorTest.php index 8c2d233e..5303fef2 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/SmartFormatPluralValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/SmartFormatPluralValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\SmartFormatPluralValidator; +use MediaWiki\Extension\Translate\Validation\Validators\SmartFormatPluralValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\SmartFormatPluralValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\SmartFormatPluralValidator */ class SmartFormatPluralValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/UnicodePluralValidatorTest.php b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/UnicodePluralValidatorTest.php index 1bd86f2f..df9a7604 100644 --- a/MLEB/Translate/tests/phpunit/unit/MessageValidator/Validators/UnicodePluralValidatorTest.php +++ b/MLEB/Translate/tests/phpunit/unit/Validation/Validators/UnicodePluralValidatorTest.php @@ -1,11 +1,11 @@ <?php declare( strict_types = 1 ); -use MediaWiki\Extensions\Translate\MessageValidator\Validators\UnicodePluralValidator; +use MediaWiki\Extension\Translate\Validation\Validators\UnicodePluralValidator; /** * @license GPL-2.0-or-later - * @covers \MediaWiki\Extensions\Translate\MessageValidator\Validators\UnicodePluralValidator + * @covers \MediaWiki\Extension\Translate\Validation\Validators\UnicodePluralValidator */ class UnicodePluralValidatorTest extends BaseValidatorTestCase { /** @dataProvider provideTestCases */ diff --git a/MLEB/Translate/tests/phpunit/unit/tag/TPParseTest.php b/MLEB/Translate/tests/phpunit/unit/tag/TPParseTest.php deleted file mode 100644 index 1228d58a..00000000 --- a/MLEB/Translate/tests/phpunit/unit/tag/TPParseTest.php +++ /dev/null @@ -1,194 +0,0 @@ -<?php -declare( strict_types = 1 ); - -/** - * @author Niklas Laxström - * @license GPL-2.0-or-later - * @covers \TPParse - */ -class TPParseTest extends \MediaWikiUnitTestCase { - public function setUp(): void { - parent::setUp(); - - if ( !defined( 'TRANSLATE_FUZZY' ) ) { - define( 'TRANSLATE_FUZZY', '!!FUZZY!!' ); - } - } - - /** @dataProvider provideTestSectionWrapping */ - public function testSectionWrapping( - bool $inline, - bool $canWrap, - array $messages, - string $expected, - string $comment - ) { - $title = Title::makeTitle( NS_MAIN, __CLASS__ ); - $prefix = $title->getPrefixedDBkey() . '/'; - - $sections = $collection = []; - foreach ( $messages as $id => $m ) { - /** @var FatMessage $m */ - $section = new TPSection(); - $section->id = $id; - $section->text = $m->definition(); - $section->setIsInline( $inline ); - $section->setCanWrap( $canWrap ); - - $sections[$id] = $section; - $collection[$prefix . $id] = $m; - } - - $parse = new TPParse( $title ); - $parse->sections = $sections; - - $glue = $inline ? ' | ' : "\n\n"; - $parse->template = implode( $glue, array_keys( $sections ) ); - - $actual = $parse->getTranslationPageText( $collection ); - $this->assertSame( - $expected, - $actual, - $comment - ); - } - - public function provideTestSectionWrapping() { - $inline = true; - $block = false; - - $wrap = true; - $nowrap = false; - - $sectionText = 'Hello'; - $fuzzyClass = 'mw-translate-fuzzy'; - - $okMessage = new FatMessage( 'ignoredKey', $sectionText ); - $okMessage->setTranslation( 'Hallo' ); - - $fuzzyMessage = new FatMessage( 'ignoredKey', $sectionText ); - $fuzzyMessage->setTranslation( 'hallo' ); - $fuzzyMessage->addTag( 'fuzzy' ); - - $untranslatedMessage = new FatMessage( 'ignoredKey', $sectionText ); - - $identicalMessage = new FatMessage( 'ignoredKey', $sectionText ); - $identicalMessage->setTranslation( $sectionText ); - - yield [ - $inline, - $wrap, - [ $okMessage ], - 'Hallo', - 'OK inline translation is not wrapped' - ]; - - yield [ - $inline, - $nowrap, - [ $okMessage ], - 'Hallo', - 'OK inline translation is not wrapped in nowrap' - ]; - - yield [ - $block, - $wrap, - [ $okMessage ], - $okMessage->translation(), - 'OK block translation is not wrapped' - ]; - - yield [ - $block, - $nowrap, - [ $okMessage ], - $okMessage->translation(), - 'OK block translation is not wrapped in nowrap' - ]; - - yield [ - $inline, - $wrap, - [ $fuzzyMessage ], - "<span class=\"$fuzzyClass\">hallo</span>", - 'Fuzzy inline translation is wrapped' - ]; - - yield [ - $inline, - $nowrap, - [ $fuzzyMessage ], - 'hallo', - 'Fuzzy inline translation is not wrapped in nowrap' - ]; - - yield [ - $block, - $wrap, - [ $fuzzyMessage ], - "<div class=\"$fuzzyClass\">\nhallo\n</div>", - 'Fuzzy block translation is wrapped' - ]; - - yield [ - $block, - $nowrap, - [ $fuzzyMessage ], - 'hallo', - 'Fuzzy block translation is not wrapped in nowrap' - ]; - - yield [ - $inline, - $wrap, - [ $identicalMessage ], - 'Hello', - 'Identically translated inline message is not wrapped' - ]; - - yield [ - $block, - $nowrap, - [ $identicalMessage ], - 'Hello', - 'Identically translated block message is not wrapped in nowrap' - ]; - - yield [ - $inline, - $wrap, - [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], - "Hallo | <span class=\"$fuzzyClass\">hallo</span> | Hello | Hello", - 'Different kinds of inline messages together are appropriately wrapped' - ]; - - yield [ - $inline, - $nowrap, - [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], - 'Hallo | hallo | Hello | Hello', - 'Different kinds of inline messages together are not wrapped in nowrap' - ]; - - $blockText = <<<WIKITEXT -Hallo - -<div class="{$fuzzyClass}"> -hallo -</div> - -Hello - -Hello -WIKITEXT; - - yield [ - $block, - $wrap, - [ $okMessage, $fuzzyMessage, $identicalMessage, $untranslatedMessage ], - $blockText, - 'Different kinds of block messages together are wrapped appropriately' - ]; - } -} diff --git a/MLEB/Translate/tests/phpunit/unit/tag/TPSectionTest.php b/MLEB/Translate/tests/phpunit/unit/tag/TPSectionTest.php deleted file mode 100644 index ae39b9b9..00000000 --- a/MLEB/Translate/tests/phpunit/unit/tag/TPSectionTest.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php -declare( strict_types = 1 ); - -/** - * @author Niklas Laxström - * @license GPL-2.0-or-later - * @covers \TPSection - */ -class TPSectionTest extends \MediaWikiUnitTestCase { - /** @dataProvider providerTestGetMarkedText */ - public function testGetMarkedText( - string $name, string $text, bool $inline, string $expected - ) { - $section = new TPSection(); - $section->name = $name; - $section->text = $text; - $section->setIsInline( $inline ); - - $output = $section->getMarkedText(); - - $this->assertEquals( $expected, $output ); - } - - /** @dataProvider providerTestGetTextWithVariables */ - public function testGetTextWithVariables( string $text, string $expected ) { - $section = new TPSection(); - $section->text = $text; - - $output = $section->getTextWithVariables(); - - $this->assertEquals( $expected, $output ); - } - - /** @dataProvider providerTestGetTextForTrans */ - public function testGetTextForTrans( string $text, string $expected ) { - $section = new TPSection(); - $section->text = $text; - - $output = $section->getTextForTrans(); - - $this->assertEquals( $expected, $output ); - } - - public static function providerTestGetMarkedText() { - $cases = []; - - // Inline syntax - $cases[] = [ - 'name', - 'Hello', - true, - '<!--T:name--> Hello', - ]; - - // Normal syntax - $cases[] = [ - 'name', - 'Hello', - false, - "<!--T:name-->\nHello", - ]; - - // Inline should not matter for headings, which have special syntax, but test both values - $cases[] = [ - 'name', - '== Hello ==', - true, - '== Hello == <!--T:name-->', - ]; - - $cases[] = [ - 'name', - '====== Hello ======', - false, - '====== Hello ====== <!--T:name-->', - ]; - - return $cases; - } - - public static function providerTestGetTextWithVariables() { - $cases = []; - - // syntax - $cases[] = [ - "<tvar|abc>Peter\n cat!</>", - '$abc', - ]; - - $cases[] = [ - "<tvar|1>Hello</>\n<tvar|2>Hello</>", - "$1\n$2", - ]; - - return $cases; - } - - public static function providerTestGetTextForTrans() { - $cases = []; - - // syntax - $cases[] = [ - "<tvar|abc>Peter\n cat!</>", - "Peter\n cat!", - ]; - - $cases[] = [ - "<tvar|1>Hello</>\n<tvar|2>Hello</>", - "Hello\nHello", - ]; - - return $cases; - } -} diff --git a/MLEB/Translate/tests/phpunit/unit/tag/TranslatablePageTest.php b/MLEB/Translate/tests/phpunit/unit/tag/TranslatablePageTest.php index a2b180ec..a1b16295 100644 --- a/MLEB/Translate/tests/phpunit/unit/tag/TranslatablePageTest.php +++ b/MLEB/Translate/tests/phpunit/unit/tag/TranslatablePageTest.php @@ -9,158 +9,6 @@ use MediaWiki\Linker\LinkTarget; * @covers \TranslatablePage */ class TranslatablePageTest extends \MediaWikiUnitTestCase { - /** @dataProvider provideTestGetTranslationPageText */ - public function testGetTranslationPageText( string $pageContents, string $expected ) { - $title = Title::makeTitle( NS_MAIN, __CLASS__ ); - $page = TranslatablePage::newFromText( $title, $pageContents ); - $prefix = $title->getPrefixedDBkey() . '/'; - $parse = $page->getParse(); - - $collection = []; - $actual = $parse->getTranslationPageText( $collection ); - $this->assertEquals( - $expected, - $actual, - 'Variable declarations are substituted when no translation' - ); - - foreach ( $parse->sections as $section ) { - $key = $prefix . $section->id; - $message = new FatMessage( $key, $section->getText() ); - $message->setTranslation( $section->getText() ); - $collection[$key] = $message; - } - - $actual = $parse->getTranslationPageText( $collection ); - $this->assertEquals( - $expected, - $actual, - 'Variable declarations are substituted in source language' - ); - - foreach ( $parse->sections as $section ) { - $key = $prefix . $section->id; - $message = new FatMessage( $key, $section->getText() ); - $message->setTranslation( $section->getTextForTrans() ); - $collection[$key] = $message; - } - $actual = $parse->getTranslationPageText( $collection ); - $this->assertEquals( - $expected, - $actual, - 'Variable declarations are substituted in translation' - ); - } - - public function provideTestGetTranslationPageText() { - yield [ - '<translate>Hello <tvar|abc>peter!</></translate>', - 'Hello peter!' - ]; - - yield [ - '<translate nowrap>Hello <tvar|abc>peter!</></translate>', - 'Hello peter!' - ]; - } - - /** @dataProvider provideTestSectionise */ - public function testSectionise( string $input, string $pattern, string $comment ) { - $canWrap = true; - $result = TranslatablePage::sectionise( $input, $canWrap ); - $pattern = addcslashes( $pattern, '~' ); - $this->assertRegExp( "~^$pattern$~", $result['template'], $comment ); - } - - public static function provideTestSectionise() { - // Ugly implicit assumption - $ph = "\x7fUNIQ[a-z0-9]{8,16}-\d+"; - - $cases = []; - - yield [ - 'Hello', - "$ph", - 'No surrounding whitespace', - ]; - - yield [ - "\nHello", - "\n$ph", - 'With surrounding whitespace', - ]; - - yield [ - "\nHello world\n\nBunny\n", - "\n$ph\n\n$ph\n", - 'Splitting at one empty line', - ]; - - yield [ - "First\n\n\n\n\nSecond\n\nThird", - "$ph\n\n\n\n\n$ph\n\n$ph", - 'Splitting with multiple empty lines', - ]; - - return $cases; - } - - /** @dataProvider provideTestCleanupTags */ - public function testCleanupTags( string $input, string $expected, string $comment ) { - $output = TranslatablePage::cleanupTags( $input ); - $this->assertEquals( $expected, $output, $comment ); - } - - public static function provideTestCleanupTags() { - yield [ - "== Hello ==\n</translate>", - '== Hello ==', - 'Unbalanced tag in a section preview', - ]; - - yield [ - "</translate><translate>", - '', - 'Unbalanced tags, no whitespace', - ]; - - yield [ - "1\n2<translate>3\n4</translate>5\n6", - "1\n23\n45\n6", - 'Balanced tags, non-removable whitespace', - ]; - - yield [ - "1<translate>\n\n</translate>2", - '12', - 'Balanced tags, removable whitespace', - ]; - - yield [ - '[[<tvar|wmf>Special:MyLanguage/Wikimedia Foundation</>|Wikimedia Foundation]].', - '[[Special:MyLanguage/Wikimedia Foundation|Wikimedia Foundation]].', - 'TVAR tag is collapsed', - ]; - - yield [ - 'You can use the <nowiki><translate></nowiki> tag.', - 'You can use the <nowiki><translate></nowiki> tag.', - 'Tag inside a nowiki is retained', - ]; - - yield [ - 'What if I <translate and </translate>.', - 'What if I <translate and .', - 'Broken tag is retained', - ]; - - yield [ - '<abbr title="<translate nowrap>Careful unselfish true engineer</translate>">CUTE</abbr>', - '<abbr title="Careful unselfish true engineer">CUTE</abbr>', - 'Nowrap is removed', - ]; - } - /** @dataProvider provideTestParseTranslationUnit */ public function testParseTranslationUnit( LinkTarget $input, array $expected ) { $output = TranslatablePage::parseTranslationUnit( $input ); diff --git a/MLEB/Translate/tests/phpunit/unit/utils/ArrayFlattenerTest.php b/MLEB/Translate/tests/phpunit/unit/utils/ArrayFlattenerTest.php index 1b72e56a..bb4f7a2c 100644 --- a/MLEB/Translate/tests/phpunit/unit/utils/ArrayFlattenerTest.php +++ b/MLEB/Translate/tests/phpunit/unit/utils/ArrayFlattenerTest.php @@ -5,9 +5,7 @@ * @license GPL-2.0-or-later */ -/** - * @coversDefaultClass \ArrayFlattener - */ +/** @coversDefaultClass \ArrayFlattener */ class ArrayFlattenerTest extends \MediaWikiUnitTestCase { /** * @dataProvider provideTestFlatten diff --git a/MLEB/Translate/tests/phpunit/unit/utils/MessageSourceChangeTest.php b/MLEB/Translate/tests/phpunit/unit/utils/MessageSourceChangeTest.php index 7929f5e9..99b71beb 100644 --- a/MLEB/Translate/tests/phpunit/unit/utils/MessageSourceChangeTest.php +++ b/MLEB/Translate/tests/phpunit/unit/utils/MessageSourceChangeTest.php @@ -4,15 +4,11 @@ * @license GPL-2.0-or-later */ -use MediaWiki\Extensions\Translate\MessageSync\MessageSourceChange; +use MediaWiki\Extension\Translate\MessageSync\MessageSourceChange; -/** - * @covers MediaWiki\Extensions\Translate\MessageSync\MessageSourceChange - */ +/** @covers MediaWiki\Extension\Translate\MessageSync\MessageSourceChange */ class MessageSourceChangeTest extends MediaWikiUnitTestCase { - /** - * @var MessageSourceChange - */ + /** @var MessageSourceChange */ protected $change; /** @@ -136,7 +132,7 @@ class MessageSourceChangeTest extends MediaWikiUnitTestCase { 'en-gb', 'renameDeleted', [ MessageSourceChange::CHANGE ] ); $this->assertNull( - $changed, 'findMessage returns null when searching changes for renamed message.' + $changed, 'findMessage returns null when searching changes for renamed message.' ); $this->change->breakRename( 'en-gb', 'renameAdded' ); diff --git a/MLEB/Translate/tests/phpunit/utils/MessageGroupCacheTest.php b/MLEB/Translate/tests/phpunit/utils/MessageGroupCacheTest.php index 06734c10..61d8e2c6 100644 --- a/MLEB/Translate/tests/phpunit/utils/MessageGroupCacheTest.php +++ b/MLEB/Translate/tests/phpunit/utils/MessageGroupCacheTest.php @@ -5,9 +5,7 @@ * @license GPL-2.0-or-later */ -/** - * @coversDefaultClass \MessageGroupCache - */ +/** @coversDefaultClass \MessageGroupCache */ class MessageGroupCacheTest extends MediaWikiIntegrationTestCase { public function testCacheRoundtrip() { $parseOutput = [ diff --git a/MLEB/Translate/tests/phpunit/utils/MessageGroupStatsTest.php b/MLEB/Translate/tests/phpunit/utils/MessageGroupStatsTest.php index 05777c5e..b26299d9 100644 --- a/MLEB/Translate/tests/phpunit/utils/MessageGroupStatsTest.php +++ b/MLEB/Translate/tests/phpunit/utils/MessageGroupStatsTest.php @@ -6,7 +6,7 @@ */ class MessageGroupStatsTest extends MediaWikiIntegrationTestCase { - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setTemporaryHook( @@ -54,7 +54,7 @@ class MessageGroupStatsTest extends MediaWikiIntegrationTestCase { $validLang = MessageGroupStats::forLanguage( 'en', MessageGroupStats::FLAG_CACHE_ONLY ); $invalidLang = MessageGroupStats::forLanguage( 'ffff', MessageGroupStats::FLAG_CACHE_ONLY ); - $validGroup = MessageGroupStats::forGroup( 'theid', MessageGroupStats::FLAG_CACHE_ONLY ); + $validGroup = MessageGroupStats::forGroup( 'theid', MessageGroupStats::FLAG_CACHE_ONLY ); $invalidGroup = MessageGroupStats::forGroup( 'invalid-mg-group', MessageGroupStats::FLAG_CACHE_ONLY ); diff --git a/MLEB/Translate/tests/phpunit/utils/MessageGroupWANCacheTest.php b/MLEB/Translate/tests/phpunit/utils/MessageGroupWANCacheTest.php index 4887b9f2..1f52ccde 100644 --- a/MLEB/Translate/tests/phpunit/utils/MessageGroupWANCacheTest.php +++ b/MLEB/Translate/tests/phpunit/utils/MessageGroupWANCacheTest.php @@ -1,8 +1,9 @@ <?php + class MessageGroupWANCacheTest extends MediaWikiIntegrationTestCase { protected $mgCache; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->mgCache = new MessageGroupWANCache( new WANObjectCache( [ 'cache' => wfGetCache( 'hash' ) ] ) diff --git a/MLEB/Translate/tests/phpunit/utils/MessageWebImporterTest.php b/MLEB/Translate/tests/phpunit/utils/MessageWebImporterTest.php index 0c9dd7b1..69a6f810 100644 --- a/MLEB/Translate/tests/phpunit/utils/MessageWebImporterTest.php +++ b/MLEB/Translate/tests/phpunit/utils/MessageWebImporterTest.php @@ -1,12 +1,10 @@ <?php -/** - * @group Database - */ +/** @group Database */ class MessageWebImporterTest extends MediaWikiIntegrationTestCase { private const PAGE = 'MediaWiki:' . __METHOD__ . '_translated'; - protected function setUp() : void { + protected function setUp(): void { parent::setUp(); $this->setTemporaryHook( 'TranslatePostInitGroups', [ $this, 'getTestGroups' ] ); @@ -27,9 +25,7 @@ class MessageWebImporterTest extends MediaWikiIntegrationTestCase { return false; } - /** - * @covers MessageWebImporter::doFuzzy - */ + /** @covers MessageWebImporter::doFuzzy */ public function testDoFuzzy() { $this->assertTrue( $this->editPage( self::PAGE . '/en', 'English Original' )->isGood(), |