wiki.techinc.nl/tests/phpunit/includes/Message/TextFormatterTest.php
Bartosz Dziewoński 9d56257d8c Make Message and MessageValue compatible
Fix two problems that made it difficult to convert between Message
and MessageValue, or to write code that could accept both of them,
as exemplified by the StatusValue class:

* Implement a common interface
* Use the same internal format for message parameters

While these changes should be compatible with most of existing code,
where the authors were courteous enough to simply call methods such
as Message::numParam() and not look inside the values they return,
it is potentially a breaking change for anything that depended on
the formatted params being arrays or accessed their keys.
Example patches: https://gerrit.wikimedia.org/r/q/topic:message-param

Notable changes:

* Message and MessageValue now both implement MessageSpecifier
  (only Message implemented it before).

* Message::numParam() and other static methods for encoding params
  now return MessageParam objects, instead of special arrays.
  Use these MessageParam objects internally in Message.

* Narrow down the return type of MessageSpecifier::getParams() (it
  was just `array`, allowing any type in the array). Narrow down the
  types for Message::params() and MessageValue::params() to match.

* Deprecate MediaWiki\Message\Converter. As a replacement add
  MessageValue::newFromSpecifier(), which is analogous to
  Message::newFromSpecifier(), but without weird legacy edge cases.

* Make StatusValue::getMessages() return MessageValues. Remove code
  that converted between Message and MessageValue, no longer needed.

* Update many type declarations and comments to use MessageSpecifier
  instead of MessageValue, as well as a couple of tests that depended
  on implementation details.

Bug: T358779
Change-Id: I625a48a6ecd3fad5c2ed76b23343a0fef91e1b83
2024-10-19 15:00:07 +02:00

130 lines
4 KiB
PHP

<?php
namespace MediaWiki\Tests\Message;
use MediaWiki\Message\Message;
use MediaWiki\Message\TextFormatter;
use MediaWiki\Message\UserGroupMembershipParam;
use MediaWiki\User\UserIdentityValue;
use MediaWikiIntegrationTestCase;
use Wikimedia\Message\MessageValue;
use Wikimedia\Message\ParamType;
use Wikimedia\Message\ScalarParam;
/**
* @covers \MediaWiki\Message\TextFormatter
* @covers \Wikimedia\Message\MessageValue
* @covers \Wikimedia\Message\ListParam
* @covers \Wikimedia\Message\ScalarParam
* @covers \Wikimedia\Message\MessageParam
*/
class TextFormatterTest extends MediaWikiIntegrationTestCase {
private function createTextFormatter( $langCode,
$includeWikitext = false,
$format = Message::FORMAT_TEXT
) {
$formatter = $this->getMockBuilder( TextFormatter::class )
->onlyMethods( [ 'createMessage' ] )
->setConstructorArgs( [ $langCode, $format ] )
->getMock();
$formatter->method( 'createMessage' )
->willReturnCallback( function ( $spec ) use ( $includeWikitext ) {
$message = $this->getMockBuilder( Message::class )
->setConstructorArgs( [ $spec ] )
->onlyMethods( [ 'fetchMessage' ] )
->getMock();
$message->method( 'fetchMessage' )
->willReturnCallback( static function () use ( $message, $includeWikitext ) {
/** @var Message $message */
$result = "{$message->getKey()} $1 $2";
if ( $includeWikitext ) {
$result .= " {{SITENAME}}";
}
return $result;
} );
return $message;
} );
return $formatter;
}
public function testGetLangCode() {
$formatter = new TextFormatter( 'fr' );
$this->assertSame( 'fr', $formatter->getLangCode() );
}
public function testFormatBitrate() {
$formatter = $this->createTextFormatter( 'en' );
$mv = ( new MessageValue( 'test' ) )->bitrateParams( 100, 200 );
$result = $formatter->format( $mv );
$this->assertSame( 'test 100 bps 200 bps', $result );
}
public function testFormatShortDuration() {
$formatter = $this->createTextFormatter( 'en' );
$mv = ( new MessageValue( 'test' ) )->shortDurationParams( 100, 200 );
$result = $formatter->format( $mv );
$this->assertSame( 'test 1 min 40 s 3 min 20 s', $result );
}
public function testFormatList() {
$formatter = $this->createTextFormatter( 'en' );
$mv = ( new MessageValue( 'test' ) )->commaListParams( [
'a',
new ScalarParam( ParamType::BITRATE, 100 ),
] );
$result = $formatter->format( $mv );
$this->assertSame( 'test a, 100 bps $2', $result );
}
public static function provideTestFormatMessage() {
yield [ ( new MessageValue( 'test' ) )
->params( new MessageValue( 'test2', [ 'a', 'b' ] ) )
->commaListParams( [
'x',
new ScalarParam( ParamType::BITRATE, 100 ),
new MessageValue( 'test3', [ 'c', new MessageValue( 'test4', [ 'd', 'e' ] ) ] )
] ),
'test (test2: a, b) x(comma-separator)(bitrate-bits)(comma-separator)(test3: c, (test4: d, e))'
];
yield [ ( new MessageValue( 'test' ) )
->userGroupParams( 'bot' ),
'test (group-bot) $2'
];
// Deprecated, silence deprecation warnings
@yield [ ( new MessageValue( 'test' ) )
->objectParams(
new UserGroupMembershipParam( 'bot', new UserIdentityValue( 1, 'user' ) )
),
'test (group-bot-member: user) $2'
];
}
/**
* @dataProvider provideTestFormatMessage
*/
public function testFormatMessage( $message, $expected ) {
$formatter = $this->createTextFormatter( 'qqx' );
$result = $formatter->format( $message );
$this->assertSame( $expected, $result );
}
public function testFormatMessageFormatsWikitext() {
global $wgSitename;
$formatter = $this->createTextFormatter( 'en', true );
$mv = MessageValue::new( 'test' )
->plaintextParams( '1', '2' );
$this->assertSame( "test 1 2 $wgSitename", $formatter->format( $mv ) );
}
public function testFormatMessageNotWikitext() {
$formatter = $this->createTextFormatter( 'en', true, Message::FORMAT_PLAIN );
$mv = MessageValue::new( 'test' )
->plaintextParams( '1', '2' );
$this->assertSame( "test 1 2 {{SITENAME}}", $formatter->format( $mv ) );
}
}