Add structure test for Messages*.php files

* Verify that the fallback chain is not too long
* Add some other obvious tests and fix the files that fail them.

Bug: T310532
Change-Id: I00f3aed35e756a3985f9f16af6d4721e2b61d3f6
This commit is contained in:
Tim Starling 2022-06-15 12:19:33 +10:00 committed by DannyS712
parent 01beedea28
commit 514d941a73
9 changed files with 154 additions and 7 deletions

View file

@ -471,5 +471,6 @@ $arabicCombiningDiacritics =
$linkTrail = '/^([a-zء-ي' . $arabicCombiningDiacritics . ']+)(.*)$/sDu';
$linkPrefixCharset = 'a-zA-Zء-ي' . $arabicCombiningDiacritics;
unset( $arabicCombiningDiacritics );
$digitGroupingPattern = "#,##0.###";

View file

@ -268,7 +268,7 @@ $magicWords = [
'pagesincategory_all' => [ 0, 'সব', 'সকল', 'all' ],
'pagesincategory_files' => [ 0, 'ফাইলসমূহ', 'files' ],
'pagesincategory_pages' => [ 0, 'পাতাসমূহ', 'পৃষ্ঠাসমূহ', 'pages' ],
'pagesincategory_subcats' => [ 0, 'উপবিষয়শ্রেণী', '', 'subcats' ],
'pagesincategory_subcats' => [ 0, 'উপবিষয়শ্রেণী', 'subcats' ],
'pagesinnamespace' => [ 1, 'নামস্থানে_পাতা', 'নামস্থানে_পৃষ্ঠা', 'নামস্থানেপাতা', 'নামস্থানেপৃষ্ঠা', 'PAGESINNAMESPACE:', 'PAGESINNS:' ],
'pagesize' => [ 1, 'পাতার_আকার', 'পাতারআকার', 'পৃষ্ঠার_আকার', 'পৃষ্ঠারআকার', 'PAGESIZE' ],
'plural' => [ 0, 'বহুবচন:', 'PLURAL:' ],

View file

@ -46,7 +46,7 @@ $specialPageAliases = [
'Ancientpages' => [ 'PáginasAntiguas', 'Páginas_antiguas' ],
'ApiHelp' => [ 'AyudaAPI', 'Ayuda_de_la_API' ],
'ApiSandbox' => [ 'Zona_de_pruebas_de_la_API' ],
'Autoblocklist' => [ 'Lista_de_bloqueos_automáticos' ],
'AutoblockList' => [ 'Lista_de_bloqueos_automáticos' ],
'Badtitle' => [ 'Título_incorrecto' ],
'Blankpage' => [ 'PáginaEnBlanco', 'Blanquear_página', 'BlanquearPágina', 'Página_en_blanco' ],
'Block' => [ 'Bloquear' ],

View file

@ -10,7 +10,6 @@
$fallback = 'hy';
/** @phpcs-require-sorted-array */
$magicWords['redirect'] = [ '#REDIRECT', '#ՎԵՐԱՀՂՈՒՄ', '#ՎԵՐԱՅՂՈՒՄ', '0' ];
$magicWords['redirect'] = [ '0', '#REDIRECT', '#ՎԵՐԱՀՂՈՒՄ', '#ՎԵՐԱՅՂՈՒՄ' ];
$namespaceNames[NS_CATEGORY] = 'Ստորոգութիւն';

View file

@ -49,3 +49,4 @@ $arabicCombiningDiacritics =
'\\x{06E8}' .
'\\x{06EA}-\\x{06ED}';
$linkTrail = '/^([a-zء-ي' . $arabicCombiningDiacritics . 'چڠڤکݢڽۏ]+)(.*)$/sDu';
unset( $arabicCombiningDiacritics );

View file

@ -117,7 +117,7 @@ $specialPageAliases = [
'Myuploads' => [ 'ကျွန်ုပ်၏ဖိုင်တင်မှုများ', 'ကျွန်ုပ်၏ဖိုင်များ' ],
'Newimages' => [ 'ဖိုင်အသစ်များ', 'ပုံအသစ်များ' ],
'Newpages' => [ 'စာမျက်နှာအသစ်များ' ],
'Pagedata' => [ 'စာမျက်နှာဒေတာ' ],
'PageData' => [ 'စာမျက်နှာဒေတာ' ],
'PasswordPolicies' => [ 'စကားဝှက်မူဝါဒများ' ],
'PasswordReset' => [ 'စကားဝှက်အသစ်ပြုလုပ်ရန်' ],
'PermanentLink' => [ 'ပုံသေလိပ်စာ' ],

View file

@ -171,7 +171,7 @@ $specialPageAliases = [
'Listbots' => [ 'Boty' ],
'ListDuplicatedFiles' => [ 'Zduplikowane_pliki' ],
'Listfiles' => [ 'Pliki' ],
'ListGrants' => [ 'Dostępy_użytkowników' ],
'Listgrants' => [ 'Dostępy_użytkowników' ],
'Listgrouprights' => [ 'Grupy_użytkowników', 'Uprawnienia_grup_użytkowników' ],
'Listredirects' => [ 'Przekierowania' ],
'Listusers' => [ 'Użytkownicy' ],

View file

@ -88,7 +88,7 @@ $specialPageAliases = [
'MIMEsearch' => [ 'HľadanieMIME' ],
'Mostcategories' => [ 'NajviacKategórií' ],
'Mostimages' => [ 'NajodkazovanejšieSúbory' ],
'MostInterwikis' => [ 'NajviacInterwiki' ],
'Mostinterwikis' => [ 'NajviacInterwiki' ],
'Mostlinked' => [ 'NajodkazovanejšieStránky' ],
'Mostlinkedcategories' => [ 'NajodkazovanejšieKategórie' ],
'Mostlinkedtemplates' => [ 'NajodkazovanejšieŠablóny' ],

View file

@ -0,0 +1,146 @@
<?php
/**
* Validate the Messages*.php files
* @coversNothing -- no way to cover non-class files
*/
class MessagesStructureTest extends \PHPUnit\Framework\TestCase {
private $langCode;
private static $enData;
public static function provideMessagesFiles() {
$n = 0;
foreach ( glob( MW_INSTALL_PATH . '/languages/messages/Messages*.php' ) as $path ) {
$fileName = basename( $path );
yield [ $fileName ];
$n++;
}
if ( $n === 0 ) {
throw new \Exception( 'Not enough files' );
}
}
/**
* @dataProvider provideMessagesFiles
* @param string $fileName
*/
public function testMessageFile( $fileName ) {
$this->langCode = Language::getCodeFromFileName( $fileName, 'Messages' );
// Like isValidBuiltInCode()
$this->assertRegExp( '/^[a-z0-9-]{2,}$/', $this->langCode );
// Check for unrecognised variable names
$path = MW_INSTALL_PATH . '/languages/messages/' . $fileName;
$vars = $this->readFile( $path );
$unknownVars = array_diff(
array_keys( $vars ),
LocalisationCache::$allKeys
);
$this->assertSame( [], $unknownVars, 'unknown variables' );
foreach ( $vars as $name => $value ) {
$method = 'validate' . ucfirst( $name );
if ( method_exists( $this, $method ) ) {
$this->$method( $value );
}
}
}
private function readFile( $_path ) {
require $_path;
$vars = get_defined_vars();
unset( $vars['_path'] );
return $vars;
}
private function getEnData() {
if ( self::$enData === null ) {
self::$enData = $this->readFile( MW_INSTALL_PATH . '/languages/messages/MessagesEn.php' );
}
return self::$enData;
}
private function validateFallback( $value ) {
if ( $this->langCode === 'en' ) {
$this->assertFalse( $value, 'fallback for en must be false' );
return;
}
$fallbacks = array_map( 'trim', explode( ',', $value ) );
$this->assertLessThanOrEqual(
MessageCache::MAX_REQUEST_LANGUAGES - 2,
count( $fallbacks ),
'fallback chain is too long (T310532)'
);
foreach ( $fallbacks as $code ) {
// Like isValidBuiltInCode()
$this->assertRegExp( '/^[a-z0-9-]{2,}$/', $code );
}
}
private function validateNamespaceNames( $names ) {
$enNames = $this->getEnData()['namespaceNames'];
$this->assertSame(
[],
array_diff( array_keys( $names ), array_keys( $enNames ) ),
'unrecognised namespace IDs'
);
foreach ( $names as $id => $name ) {
$this->assertIsString( $name );
if ( $id !== NS_MAIN ) {
$this->assertNotSame( '', $name );
}
}
}
private function validateMagicWords( $magicWords ) {
$enWords = $this->getEnData()['magicWords'];
$this->assertSame(
[],
array_diff( array_keys( $magicWords ), array_keys( $enWords ) ),
'unrecognised magic word IDs'
);
foreach ( $magicWords as $id => $parts ) {
// Ideally the case should be an integer, but some script writes it as a string
$case = $parts[0];
$this->assertThat(
[ 0, 1, '0', '1' ],
$this->containsIdentical( $case ),
"$id case should be 0 or 1"
);
array_shift( $parts );
foreach ( $parts as $i => $syn ) {
$this->assertIsString( $syn, "$id syn $i should be string" );
$this->assertNotSame( '', $syn, "$id syn $i should not be empty" );
}
$canonical = $enWords[$id][1];
$this->assertContains( $canonical, $parts,
"$id should contain English synonym $canonical" );
}
}
private function validateSpecialPageAliases( $pages ) {
$enPages = $this->getEnData()['specialPageAliases'];
$this->assertSame(
[],
array_diff( array_keys( $pages ), array_keys( $enPages ) ),
'unrecognised special page IDs'
);
foreach ( $pages as $pageName => $aliases ) {
foreach ( $aliases as $i => $alias ) {
$this->assertIsString( $alias, "$pageName alias $i should be string" );
$this->assertNotSame( '', $alias,
"$pageName alias $i should not be empty" );
}
}
}
private function validateLinkTrail( $linkTrail ) {
$this->assertIsString( $linkTrail );
$result = preg_match( $linkTrail, 'test' );
if ( $result === false ) {
$this->fail( "linkTrail regex match failed with code " . preg_last_error() );
}
}
}