mediawiki-extensions-Cite/tests/phpunit/integration/FootnoteMarkFormatterTest.php
thiemowmde ec9c8bda00 Use slightly narrower interfaces in a few places
The idea is to make the code less ambiguous and easier to predict.
We passed the same information around two times in a few places.

Change-Id: I39c7a2962bb70bbe40074986e63b1051d0766ea2
2024-06-24 08:07:19 +00:00

189 lines
5.5 KiB
PHP

<?php
namespace Cite\Tests\Integration;
use Cite\AnchorFormatter;
use Cite\Cite;
use Cite\ErrorReporter;
use Cite\FootnoteMarkFormatter;
use Cite\ReferenceMessageLocalizer;
use Cite\Tests\TestUtils;
use MediaWiki\Message\Message;
use MediaWiki\Parser\Parser;
use Wikimedia\TestingAccessWrapper;
/**
* @covers \Cite\FootnoteMarkFormatter
* @license GPL-2.0-or-later
*/
class FootnoteMarkFormatterTest extends \MediaWikiIntegrationTestCase {
/**
* @dataProvider provideLinkRef
*/
public function testLinkRef( array $ref, string $expectedOutput ) {
$mockErrorReporter = $this->createMock( ErrorReporter::class );
$mockErrorReporter->method( 'plain' )->willReturnCallback(
static fn ( $parser, ...$args ) => implode( '|', $args )
);
$anchorFormatter = $this->createMock( AnchorFormatter::class );
$anchorFormatter->method( 'jumpLink' )->willReturnArgument( 0 );
$anchorFormatter->method( 'backLinkTarget' )->willReturnCallback(
static fn ( ...$args ) => implode( '+', $args )
);
$messageLocalizer = $this->createMock( ReferenceMessageLocalizer::class );
$messageLocalizer->method( 'localizeSeparators' )->willReturnArgument( 0 );
$messageLocalizer->method( 'localizeDigits' )->willReturnArgument( 0 );
$messageLocalizer->method( 'msg' )->willReturnCallback(
function ( $key, ...$params ) {
$customizedGroup = $key === 'cite_link_label_group-foo';
$msg = $this->createMock( Message::class );
$msg->method( 'isDisabled' )->willReturn( !$customizedGroup );
$msg->method( 'plain' )->willReturn( $customizedGroup
? 'a b c'
: "($key|" . implode( '|', $params ) . ')'
);
return $msg;
}
);
$mockParser = $this->createNoOpMock( Parser::class, [ 'recursiveTagParse' ] );
$mockParser->method( 'recursiveTagParse' )->willReturnArgument( 0 );
$formatter = new FootnoteMarkFormatter(
$mockErrorReporter,
$anchorFormatter,
$messageLocalizer
);
$ref = TestUtils::refFromArray( $ref );
$output = $formatter->linkRef( $mockParser, $ref );
$this->assertSame( $expectedOutput, $output );
}
public static function provideLinkRef() {
return [
'Default label' => [
[
'name' => null,
'group' => '',
'number' => 50003,
'key' => 50004,
],
'(cite_reference_link|50004+|50004|50003)'
],
'Default label, named group' => [
[
'name' => null,
'group' => 'bar',
'number' => 3,
'key' => 4,
],
'(cite_reference_link|4+|4|bar 3)'
],
'Custom label' => [
[
'name' => null,
'group' => 'foo',
'number' => 3,
'key' => 4,
],
'(cite_reference_link|4+|4|c)'
],
'Custom label overrun' => [
[
'name' => null,
'group' => 'foo',
'number' => 10,
'key' => 4,
],
'(cite_reference_link|4+|4|' .
'cite_error_no_link_label_group&#124;foo&#124;cite_link_label_group-foo)'
],
'Named ref' => [
[
'name' => 'a',
'group' => '',
'number' => 3,
'key' => 4,
'count' => 1,
],
'(cite_reference_link|a+4-0|a-4|3)'
],
'Named ref reused' => [
[
'name' => 'a',
'group' => '',
'number' => 3,
'key' => 4,
'count' => 50002,
],
'(cite_reference_link|a+4-50001|a-4|3)'
],
'Subreference' => [
[
'name' => null,
'group' => '',
'number' => 3,
'key' => 4,
'extends' => 'b',
'extendsIndex' => 50002,
],
'(cite_reference_link|4+|4|3.50002)'
],
];
}
/**
* @dataProvider provideCustomizedLinkLabels
*/
public function testFetchCustomizedLinkLabel( $expectedLabel, $offset, $group, $labelList ) {
$mockMessageLocalizer = $this->createMock( ReferenceMessageLocalizer::class );
$mockMessageLocalizer->method( 'msg' )->willReturnCallback(
function ( ...$args ) use ( $labelList ) {
$msg = $this->createMock( Message::class );
$msg->method( 'isDisabled' )->willReturn( $labelList === null );
$msg->method( 'plain' )->willReturn( $labelList );
return $msg;
}
);
$mockErrorReporter = $this->createMock( ErrorReporter::class );
$mockErrorReporter->method( 'plain' )->willReturnCallback(
static fn ( $parser, ...$args ) => implode( '|', $args )
);
/** @var FootnoteMarkFormatter $formatter */
$formatter = TestingAccessWrapper::newFromObject( new FootnoteMarkFormatter(
$mockErrorReporter,
$this->createMock( AnchorFormatter::class ),
$mockMessageLocalizer
) );
$parser = $this->createNoOpMock( Parser::class );
$output = $formatter->fetchCustomizedLinkLabel( $parser, $group, $offset );
$this->assertSame( $expectedLabel, $output );
}
public static function provideCustomizedLinkLabels() {
yield [ null, 1, '', null ];
yield [ null, 2, '', null ];
yield [ null, 1, 'foo', null ];
yield [ null, 2, 'foo', null ];
yield [ 'a', 1, 'foo', 'a b c' ];
yield [ 'b', 2, 'foo', 'a b c' ];
yield [ 'å', 1, 'foo', 'å β' ];
yield [ 'cite_error_no_link_label_group|foo|cite_link_label_group-foo', 4, 'foo', 'a b c' ];
}
public function testDefaultGroupCannotHaveCustomLinkLabels() {
/** @var FootnoteMarkFormatter $formatter */
$formatter = TestingAccessWrapper::newFromObject( new FootnoteMarkFormatter(
$this->createNoOpMock( ErrorReporter::class ),
$this->createNoOpMock( AnchorFormatter::class ),
// Assert that ReferenceMessageLocalizer::msg( 'cite_link_label_group-' ) isn't called
$this->createNoOpMock( ReferenceMessageLocalizer::class )
) );
$parser = $this->createNoOpMock( Parser::class );
$this->assertNull( $formatter->fetchCustomizedLinkLabel( $parser, Cite::DEFAULT_GROUP, 1 ) );
}
}