wiki.techinc.nl/tests/phpunit/unit/includes/parser/Parsoid/LanguageVariantConverterUnitTest.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

528 lines
16 KiB
PHP
Raw Normal View History

<?php
namespace MediaWiki\Tests\Parser\Parsoid;
use Language;
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
use LanguageCode;
use LanguageConverter;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Languages\LanguageFactory;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\PageIdentityValue;
use MediaWiki\Parser\Parsoid\Config\PageConfig;
use MediaWiki\Parser\Parsoid\Config\PageConfigFactory;
use MediaWiki\Parser\Parsoid\Config\SiteConfig;
use MediaWiki\Parser\Parsoid\LanguageVariantConverter;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleFactory;
use MediaWikiUnitTestCase;
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\MockObject\MockObject;
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
use Wikimedia\Bcp47Code\Bcp47Code;
use Wikimedia\Bcp47Code\Bcp47CodeValue;
use Wikimedia\Parsoid\Core\PageBundle;
use Wikimedia\Parsoid\Parsoid;
/**
* @covers \MediaWiki\Parser\Parsoid\LanguageVariantConverter
*/
class LanguageVariantConverterUnitTest extends MediaWikiUnitTestCase {
/** @dataProvider provideSetConfig */
public function testSetConfig( bool $shouldPageConfigFactoryBeUsed ) {
// Decide what should be called and what should not be
$shouldParsoidBeUsed = true;
$isLanguageConversionEnabled = true;
// Set expected language codes
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
// *These are all MediaWiki-internal codes*
$pageBundleLanguageCode = 'zh';
$titleLanguageCode = 'zh-hans';
$targetLanguageCode = 'zh-hans';
$sourceLanguageCode = null;
// Create mocks
$pageConfigMock = $this->getPageConfigMock();
$pageBundleMock = $this->getPageBundleMock( $pageBundleLanguageCode );
$languageVariantConverter = $this->getLanguageVariantConverter(
$shouldParsoidBeUsed,
$shouldPageConfigFactoryBeUsed,
$isLanguageConversionEnabled,
$pageBundleLanguageCode,
null,
$titleLanguageCode,
$targetLanguageCode,
$sourceLanguageCode
);
if ( !$shouldPageConfigFactoryBeUsed ) {
$languageVariantConverter->setPageConfig( $pageConfigMock );
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$languageFactoryMock = $this->getLanguageFactoryMock();
$languageVariantConverter->convertPageBundleVariant(
$pageBundleMock,
new Bcp47CodeValue( $targetLanguageCode )
);
}
public static function provideSetConfig() {
yield 'PageConfigFactory should not be used if PageConfig is set' => [ false ];
yield 'PageConfigFactory should be used if PageConfig is not set' => [ true ];
}
/** @dataProvider provideSourceLanguage */
public function testSourceLanguage(
?string $pageBundleLanguageCode,
?string $titleLanguageCode,
?string $contentLanguageOverride,
?string $targetLanguageCode,
?string $sourceLanguageCode,
?string $expectedSourceCode
) {
// Decide what should be called and what should not be
$shouldParsoidBeUsed = true;
$shouldPageConfigFactoryBeUsed = true;
$isLanguageConversionEnabled = true;
// Set expected language codes
$titleLanguageCode ??= 'en';
$targetLanguageCode ??= $titleLanguageCode;
// Create mocks
if ( $pageBundleLanguageCode ) {
$pageBundleMock = $this->getPageBundleMock( $pageBundleLanguageCode );
} else {
$pageBundleMock = $this->getPageBundleMockWithoutLanguage();
}
$languageVariantConverter = $this->getLanguageVariantConverter(
$shouldParsoidBeUsed,
$shouldPageConfigFactoryBeUsed,
$isLanguageConversionEnabled,
$pageBundleLanguageCode,
$contentLanguageOverride,
$titleLanguageCode,
$targetLanguageCode, // expected target language
$expectedSourceCode
);
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$targetLanguage = new Bcp47CodeValue( $targetLanguageCode );
$sourceLanguage = $sourceLanguageCode ? new Bcp47CodeValue( $sourceLanguageCode ) : null;
$languageVariantConverter->convertPageBundleVariant( $pageBundleMock, $targetLanguage, $sourceLanguage );
}
public static function provideSourceLanguage() {
yield 'content-language in PageBundle' => [
'sr', // PageBundle content-language
null, // Title PageLanguage
null, // PageLanguage override
'sr-Cyrl', // target
'sr-Cyrl', // explicit source
'sr-Cyrl' // expected source
];
yield 'content-language but no source language' => [
'en', // PageBundle content-language
null, // Title PageLanguage
null, // PageLanguage override
'en', // target
null, // explicit source
null // expected source
];
yield 'content-language is variant' => [
'en-ca', // PageBundle content-language
null, // Title PageLanguage
null, // PageLanguage override
'en', // target
null, // explicit source
'en-ca' // expected source
];
yield 'Source variant is given' => [
null, // PageBundle content-language
null, // Title PageLanguage
null, // PageLanguage override
'en', // target
'en-ca', // explicit source
'en-ca' // expected source
];
yield 'Source variant is a base language' => [
null, // PageBundle content-language
null, // Title PageLanguage
null, // PageLanguage override
'en', // target
'en', // explicit source
null // expected source
];
yield 'Page language override is variant' => [
null, // PageBundle content-language
null, // PageBundle content-language
'en-ca', // PageLanguage override
'en', // target
'en-ca', // explicit source
'en-ca' // expected source
];
}
/** @dataProvider provideSiteConfiguration */
public function testSiteConfiguration(
bool $isLanguageConversionEnabled,
bool $shouldParsoidBeUsed,
bool $shouldPageConfigFactoryBeUsed
) {
// Set expected language codes
$pageBundleLanguageCode = 'zh';
$titleLanguageCode = 'zh-hans';
$targetLanguageCode = 'zh-hans';
$sourceLanguageCode = null;
// Create mocks
$pageBundleMock = $this->getPageBundleMock( $pageBundleLanguageCode );
$languageVariantConverter = $this->getLanguageVariantConverter(
$shouldParsoidBeUsed,
$shouldPageConfigFactoryBeUsed,
$isLanguageConversionEnabled,
$pageBundleLanguageCode,
null,
$titleLanguageCode,
$targetLanguageCode,
$sourceLanguageCode
);
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$languageFactoryMock = $this->getLanguageFactoryMock();
$targetLanguage = $languageFactoryMock->getLanguage( $targetLanguageCode );
$languageVariantConverter->convertPageBundleVariant( $pageBundleMock, $targetLanguage );
}
public static function provideSiteConfiguration() {
$isLanguageConversionEnabled = false;
$shouldParsoidBeUsed = false;
$shouldPageConfigFactoryBeUsed = false;
yield 'If language conversion is disabled, parsoid and page config factory should not be used' =>
[ $isLanguageConversionEnabled, $shouldParsoidBeUsed, $shouldPageConfigFactoryBeUsed ];
$isLanguageConversionEnabled = true;
$shouldParsoidBeUsed = true;
$shouldPageConfigFactoryBeUsed = true;
yield 'If language conversion is enabled, parsoid and page config factory should be used' =>
[ $isLanguageConversionEnabled, $shouldParsoidBeUsed, $shouldPageConfigFactoryBeUsed ];
}
/**
* @param bool $shouldParsoidBeUsed
* @param bool $shouldPageConfigFactoryBeUsed
* @param bool $isLanguageConversionEnabled
* @param string|null $pageBundleLanguageCode
* @param string|null $contentLanguageOverride
* @param string $titleLanguageCode
* @param string $targetLanguageCode
* @param string|null $sourceLanguageCode
*
* @return LanguageVariantConverter
*/
private function getLanguageVariantConverter(
bool $shouldParsoidBeUsed,
bool $shouldPageConfigFactoryBeUsed,
bool $isLanguageConversionEnabled,
?string $pageBundleLanguageCode,
?string $contentLanguageOverride,
string $titleLanguageCode,
string $targetLanguageCode,
?string $sourceLanguageCode
): LanguageVariantConverter {
// If Content language is set, use language from there,
// If PageBundle language code is set, use that
// Else, fallback to title page language
$pageLanguageCode = $contentLanguageOverride ?? $pageBundleLanguageCode ?? $titleLanguageCode;
// The page language code should not be a variant
$pageLanguageCode = preg_replace( '/-.*$/', '', $pageLanguageCode );
$shouldSiteConfigBeUsed = true;
$pageIdentityValue = new PageIdentityValue( 1, NS_MAIN, 'hello_world', PageIdentity::LOCAL );
// Create the necessary mocks
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$languageFactoryMock = $this->getLanguageFactoryMock();
$pageLanguage = new Bcp47CodeValue( $pageLanguageCode );
$sourceLanguage = $sourceLanguageCode ? new Bcp47CodeValue( $sourceLanguageCode ) : null;
$targetLanguage = new Bcp47CodeValue( $targetLanguageCode );
$pageConfigMock = $this->getPageConfigMock();
$pageConfigFactoryMock = $this->getPageConfigFactoryMock(
$shouldPageConfigFactoryBeUsed,
// Expected arguments to PageConfigFactory mock
[ $pageIdentityValue, null, null, null, $this->constraintEquals( $pageLanguage ) ],
$pageConfigMock
);
$pageBundleMock = $this->getPageBundleMock( $pageBundleLanguageCode );
$siteConfigMock = $this->getSiteConfigMock(
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$shouldSiteConfigBeUsed, $pageLanguage, $isLanguageConversionEnabled
);
$titleFactoryMock = $this->getTitleFactoryMock( $pageIdentityValue, $titleLanguageCode );
$parsoidMock = $this->getParsoidMock(
$shouldParsoidBeUsed,
[
$pageConfigMock,
'variant',
$pageBundleMock,
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$this->constraintEquals( [
'variant' => [
'source' => $sourceLanguage,
'target' => $targetLanguage,
]
] )
]
);
$languageVariantConverter = new LanguageVariantConverter(
$pageIdentityValue,
$pageConfigFactoryMock,
$parsoidMock,
$siteConfigMock,
$titleFactoryMock,
$this->getLanguageConverterFactoryMock(),
$languageFactoryMock
);
if ( $contentLanguageOverride ) {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$languageVariantConverter->setPageLanguageOverride(
$languageFactoryMock->getLanguage( $contentLanguageOverride )
);
}
return $languageVariantConverter;
}
// Mock methods follow
/**
* @param bool $shouldBeCalled
* @param array $arguments
* @param PageConfig $pageConfig
*
* @return MockObject|PageConfigFactory
*/
private function getPageConfigFactoryMock( bool $shouldBeCalled, array $arguments, PageConfig $pageConfig ) {
$mock = $this->createMock( PageConfigFactory::class );
if ( $shouldBeCalled ) {
$mock->expects( $this->once() )
->method( 'create' )
->with( ...$arguments )
->willReturn( $pageConfig );
} else {
$mock->expects( $this->never() )
->method( 'create' );
}
return $mock;
}
/**
* @param bool $shouldBeCalled
* @param array $arguments
*
* @return MockObject|Parsoid
*/
private function getParsoidMock( bool $shouldBeCalled, array $arguments ) {
$mock = $this->createMock( Parsoid::class );
if ( $shouldBeCalled ) {
$mock->expects( $this->once() )
->method( 'pb2pb' )
->with( ...$arguments );
} else {
$mock->expects( $this->never() )
->method( 'pb2pb' );
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$mock->method( 'implementsLanguageConversionBcp47' )
->willReturn( true );
return $mock;
}
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
/**
* Mock constraint helper to compare equality when there are
* Bcp47Code instances involved.
* @param mixed $expected The expected value, with embedded Bcp47Codes
* @return Constraint a PHPUnit equality constrait
*/
private function constraintEquals( $expected ): Constraint {
return $this->callback( static function ( $actual ) use ( $expected ) {
return self::arrayWithCodeEquals( $expected, $actual );
} );
}
/**
* Compare two values for equality, using case-insensitive BCP-47 code
* comparisons for Bcp47Code instances.
* @param mixed $expected
* @param mixed $actual
* @return bool True if the objects should be considered equal, false otherwise.
*/
private static function arrayWithCodeEquals( $expected, $actual ) {
if ( $actual === $expected ) {
return true;
}
if ( is_array( $actual ) && is_array( $expected ) ) {
if ( count( $actual ) !== count( $expected ) ) {
return false;
}
foreach ( $expected as $key => $value ) {
if ( !array_key_exists( $key, $actual ) ) {
return false;
}
if ( !self::arrayWithCodeEquals( $value, $actual[$key] ) ) {
return false;
}
}
return true;
}
if ( $actual instanceof Bcp47Code && $expected instanceof Bcp47Code ) {
# BCP-47 codes are case insensitive.
return strcasecmp( $actual->toBcp47Code(), $expected->toBcp47Code() ) == 0;
}
return false;
}
/**
* @param bool $shouldBeCalled
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
* @param Bcp47Code $baseLanguage
* @param bool $isLanguageConversionEnabled
*
* @return MockObject|SiteConfig
*/
private function getSiteConfigMock(
bool $shouldBeCalled,
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
Bcp47Code $baseLanguage,
bool $isLanguageConversionEnabled
) {
$mock = $this->createMock( SiteConfig::class );
if ( $shouldBeCalled ) {
$mock->expects( $this->once() )
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
->method( 'langConverterEnabledBcp47' )
->with( $this->constraintEquals( $baseLanguage ) )
->willReturn( $isLanguageConversionEnabled );
} else {
$mock->expects( $this->never() )
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
->method( 'langConverterEnabledBcp47' );
}
return $mock;
}
/**
* @param PageIdentity $pageIdentity
* @param string $languageCode
*
* @return MockObject|TitleFactory
*/
private function getTitleFactoryMock( PageIdentity $pageIdentity, string $languageCode ) {
$languageMock = $this->getLanguageMock( $languageCode );
$titleMock = $this->createMock( Title::class );
$titleMock->method( 'getPageLanguage' )
->willReturn( $languageMock );
$mock = $this->createMock( TitleFactory::class );
$mock->expects( $this->once() )
->method( 'newFromPageIdentity' )
->willReturn( $titleMock )
->with( $pageIdentity );
return $mock;
}
/**
* @return MockObject|LanguageFactory
*/
private function getLanguageFactoryMock() {
$mock = $this->createMock( LanguageFactory::class );
$mock->method( 'getLanguage' )
->willReturnCallback( function ( $code ) {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
static $seen = [];
if ( $code instanceof Bcp47Code ) {
$code = LanguageCode::bcp47ToInternal( $code );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
}
if ( !isset( $seen[$code] ) ) {
$seen[$code] = $this->getLanguageMock( $code );
}
return $seen[$code];
} );
$mock->method( 'getParentLanguage' )
->willReturnCallback( static function ( $code ) use ( $mock ) {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
if ( $code instanceof Bcp47Code ) {
$code = LanguageCode::bcp47ToInternal( $code );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
}
$code = preg_replace( '/-.*$/', '', $code );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
return $mock->getLanguage( $code );
} );
return $mock;
}
/**
* @return MockObject|PageBundle
*/
private function getPageBundleMockWithoutLanguage() {
return $this->getPageBundleMock( null );
}
/**
* @param string|null $languageCode
*
* @return MockObject|PageBundle
*/
private function getPageBundleMock( ?string $languageCode ) {
$mock = $this->createMock( PageBundle::class );
$mock->headers = [
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
# T320662: this should probably be a BCP-47 code, not internal
'content-language' => $languageCode
];
$mock->html = 'test message';
return $mock;
}
/**
* @return MockObject|PageConfig
*/
private function getPageConfigMock() {
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$mock = $this->createNoOpMock( PageConfig::class, [ 'setVariantBcp47' ] );
return $mock;
}
/**
* @param string $languageCode
*
* @return MockObject|Language
*/
private function getLanguageMock( $languageCode ): Language {
$languageMock = $this->createMock( Language::class );
$languageMock->method( 'getCode' )
->willReturn( $languageCode );
Use Bcp47Code when interfacing with Parsoid It is very easy for developers and maintainers to mix up "internal MediaWiki language codes" and "BCP-47 language codes"; the latter are standards-compliant and used in web protocols like HTTP, HTML, and SVG; but much of WMF production is very dependent on historical codes used by MediaWiki which in some cases predate the IANA standardized name for the language in question. Phan and other static checking tools aren't much help distinguishing BCP-47 from internal codes when both are represented with the PHP string type, so the wikimedia/bcp-47-code package introduced a very lightweight wrapper type in order to uniquely identify BCP-47 codes. Language implements Bcp47Code, and LanguageFactory::getLanguage() is an easy way to convert (or downcast) between Bcp47Code and Language objects. This patch updates the Parsoid integration code and the associated REST handlers to use Bcp47Code in APIs so that the standalone Parsoid library does not need to know anything about MediaWiki-internal codes. The principle has been, first, to try to convert a string to a Bcp47Code as soon as possible and as close to the original input as possible, so it is easy to see *why* a given string is a BCP-47 code (usually, because it is coming from HTTP/HTML/etc) and we're not stuck deep inside some method trying to figure out where a string we're given is coming from and therefore what sort of string code it might be. Second, we've added explicit compatibility code to accept MediaWiki internal codes and convert them to Bcp47Code for backward compatibility with existing clients, using the @internal LanguageCode::normalizeNonstandardCodeAndWarn() method. The intention is to gradually remove these backward compatibility thunks and replace them with HTTP 400 errors or wfDeprecated messages in order to identify and repair callers who are incorrectly using non-standard-compliant language codes in web standards (HTTP/HTML/SVG/etc). Finally, maintaining a code as a Bcp47Code and not immediately converting to Language helps us delay or even avoid full loading of a Language object in some cases, which is another reason to occasionally push Bcp47Code (instead of Language) down the call stack. Bug: T327379 Depends-On: I830867d58f8962d6a57be16ce3735e8384f9ac1c Change-Id: I982e0df706a633b05dcc02b5220b737c19adc401
2022-11-04 17:29:23 +00:00
$languageMock->method( 'toBcp47Code' )
->willReturn( LanguageCode::bcp47( $languageCode ) );
return $languageMock;
}
private function getLanguageConverterFactoryMock() {
$languageConverterFactoryMock = $this->createMock( LanguageConverterFactory::class );
$languageConverter = $this->createMock( LanguageConverter::class );
$languageConverter->method( 'convertTo' )
->willReturnCallback( static function ( $text, $code ) {
return $text;
} );
$languageConverter->method( 'hasVariant' )
->willReturnCallback( static function ( $code ) {
return true;
} );
$languageConverterFactoryMock->method( 'getLanguageConverter' )
->willReturn( $languageConverter );
return $languageConverterFactoryMock;
}
}