2019-11-08 14:46:52 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Cite\Tests\Unit;
|
|
|
|
|
2019-11-19 14:12:11 +00:00
|
|
|
use Cite\Cite;
|
2019-11-27 11:09:31 +00:00
|
|
|
use Cite\CiteErrorReporter;
|
|
|
|
use Cite\ReferenceStack;
|
2019-11-08 14:46:52 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
|
|
|
|
/**
|
2019-11-19 14:12:11 +00:00
|
|
|
* @coversDefaultClass \Cite\Cite
|
2019-11-19 10:31:08 +00:00
|
|
|
*
|
|
|
|
* @license GPL-2.0-or-later
|
2019-11-08 14:46:52 +00:00
|
|
|
*/
|
2019-11-27 10:15:39 +00:00
|
|
|
class CiteUnitTest extends \MediaWikiUnitTestCase {
|
2019-11-08 14:46:52 +00:00
|
|
|
|
|
|
|
protected function setUp() : void {
|
2019-11-28 14:35:23 +00:00
|
|
|
global $wgCiteBookReferencing;
|
2019-11-08 14:46:52 +00:00
|
|
|
|
|
|
|
parent::setUp();
|
|
|
|
$wgCiteBookReferencing = true;
|
|
|
|
}
|
|
|
|
|
2019-11-27 11:09:31 +00:00
|
|
|
/**
|
|
|
|
* @covers ::validateRef
|
|
|
|
* @dataProvider provideValidations
|
|
|
|
*/
|
|
|
|
public function testValidateRef(
|
|
|
|
array $referencesStack,
|
|
|
|
?string $inReferencesGroup,
|
|
|
|
bool $isSectionPreview,
|
|
|
|
?string $text,
|
|
|
|
?string $name,
|
|
|
|
?string $group,
|
|
|
|
?string $follow,
|
|
|
|
?string $extends,
|
|
|
|
$expected
|
|
|
|
) {
|
2019-11-28 14:39:58 +00:00
|
|
|
/** @var CiteErrorReporter $errorReporter */
|
2019-11-27 11:09:31 +00:00
|
|
|
$errorReporter = $this->createMock( CiteErrorReporter::class );
|
|
|
|
/** @var ReferenceStack $stack */
|
|
|
|
$stack = TestingAccessWrapper::newFromObject( new ReferenceStack( $errorReporter ) );
|
|
|
|
$stack->refs = $referencesStack;
|
|
|
|
|
|
|
|
/** @var Cite $cite */
|
|
|
|
$cite = TestingAccessWrapper::newFromObject( new Cite() );
|
|
|
|
$cite->referenceStack = $stack;
|
|
|
|
$cite->inReferencesGroup = $inReferencesGroup;
|
|
|
|
$cite->isSectionPreview = $isSectionPreview;
|
|
|
|
|
|
|
|
$status = $cite->validateRef( $text, $name, $group, $follow, $extends );
|
|
|
|
if ( is_string( $expected ) ) {
|
|
|
|
$this->assertSame( $expected, $status->getErrors()[0]['message'] );
|
|
|
|
} else {
|
|
|
|
$this->assertSame( $expected, $status->isOK(), $status->getErrors()[0]['message'] ?? '' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function provideValidations() {
|
|
|
|
return [
|
|
|
|
// Validating <ref> outside of <references>
|
|
|
|
'text-only <ref>' => [
|
|
|
|
'referencesStack' => [],
|
|
|
|
'inReferencesGroup' => null,
|
|
|
|
'isSectionPreview' => false,
|
|
|
|
'text' => 't',
|
|
|
|
'name' => null,
|
|
|
|
'group' => null,
|
|
|
|
'follow' => null,
|
|
|
|
'extends' => null,
|
|
|
|
'expected' => true,
|
|
|
|
],
|
|
|
|
'totally empty <ref>' => [
|
|
|
|
'referencesStack' => [],
|
|
|
|
'inReferencesGroup' => null,
|
|
|
|
'isSectionPreview' => false,
|
|
|
|
'text' => null,
|
|
|
|
'name' => null,
|
|
|
|
'group' => null,
|
|
|
|
'follow' => null,
|
|
|
|
'extends' => null,
|
|
|
|
'expected' => 'cite_error_ref_no_key',
|
|
|
|
],
|
|
|
|
// TODO: Add test cases that trigger all possible code paths
|
|
|
|
|
|
|
|
// Validating a <ref> in <references>
|
|
|
|
'most trivial <ref> in <references>' => [
|
|
|
|
'referencesStack' => [ 'g' => [ 'n' => [] ] ],
|
|
|
|
'inReferencesGroup' => 'g',
|
|
|
|
'isSectionPreview' => false,
|
|
|
|
'text' => 'not empty',
|
|
|
|
'name' => 'n',
|
|
|
|
'group' => 'g',
|
|
|
|
'follow' => null,
|
|
|
|
'extends' => null,
|
|
|
|
'expected' => true,
|
|
|
|
],
|
|
|
|
// TODO: Add test cases that trigger all possible code paths
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2019-11-08 14:46:52 +00:00
|
|
|
/**
|
2019-11-27 12:50:05 +00:00
|
|
|
* @covers ::parseArguments
|
2019-11-08 14:46:52 +00:00
|
|
|
* @dataProvider provideRefAttributes
|
|
|
|
*/
|
2019-11-26 11:05:51 +00:00
|
|
|
public function testParseRefAttributes(
|
|
|
|
array $attributes,
|
|
|
|
array $expectedValue,
|
|
|
|
string $expectedError = null
|
|
|
|
) {
|
2019-11-08 14:46:52 +00:00
|
|
|
/** @var Cite $cite */
|
|
|
|
$cite = TestingAccessWrapper::newFromObject( new Cite() );
|
2019-11-26 11:05:51 +00:00
|
|
|
$status = $cite->parseArguments(
|
2019-11-27 12:50:05 +00:00
|
|
|
$attributes,
|
|
|
|
[ 'dir', 'extends', 'follow', 'group', 'name' ]
|
|
|
|
);
|
2019-11-26 11:05:51 +00:00
|
|
|
$this->assertSame( $expectedValue, array_values( $status->getValue() ) );
|
|
|
|
$this->assertSame( !$expectedError, $status->isOK() );
|
|
|
|
if ( $expectedError ) {
|
|
|
|
$this->assertSame( $expectedError, $status->getErrors()[0]['message'] );
|
|
|
|
}
|
2019-11-08 14:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function provideRefAttributes() {
|
2019-11-27 11:44:25 +00:00
|
|
|
// Note: Values are guaranteed to be trimmed by the parser, see
|
|
|
|
// Sanitizer::decodeTagAttributes()
|
2019-11-08 14:46:52 +00:00
|
|
|
return [
|
2019-11-22 08:49:27 +00:00
|
|
|
[ [], [ null, null, null, null, null ] ],
|
2019-11-08 14:46:52 +00:00
|
|
|
|
|
|
|
// One attribute only
|
2019-11-26 11:18:55 +00:00
|
|
|
[ [ 'dir' => 'invalid' ], [ 'invalid', null, null, null, null ] ],
|
2019-11-27 11:44:25 +00:00
|
|
|
[ [ 'dir' => 'rtl' ], [ 'rtl', null, null, null, null ] ],
|
|
|
|
[ [ 'follow' => 'f' ], [ null, null, 'f', null, null ] ],
|
|
|
|
[ [ 'group' => 'g' ], [ null, null, null, 'g', null ] ],
|
2019-11-26 11:05:51 +00:00
|
|
|
[
|
|
|
|
[ 'invalid' => 'i' ],
|
|
|
|
[ null, null, null, null, null ],
|
|
|
|
'cite_error_ref_too_many_keys'
|
|
|
|
],
|
|
|
|
[
|
|
|
|
[ 'invalid' => null ],
|
|
|
|
[ null, null, null, null, null ],
|
|
|
|
'cite_error_ref_too_many_keys'
|
|
|
|
],
|
2019-11-27 11:44:25 +00:00
|
|
|
[ [ 'name' => 'n' ], [ null, null, null, null, 'n' ] ],
|
2019-11-27 12:50:05 +00:00
|
|
|
[ [ 'name' => null ], [ null, null, null, null, null ] ],
|
2019-11-27 11:44:25 +00:00
|
|
|
[ [ 'extends' => 'e' ], [ null, 'e', null, null, null ] ],
|
2019-11-08 14:46:52 +00:00
|
|
|
|
|
|
|
// Pairs
|
2019-11-26 11:18:55 +00:00
|
|
|
[ [ 'follow' => 'f', 'name' => 'n' ], [ null, null, 'f', null, 'n' ] ],
|
2019-11-27 12:50:05 +00:00
|
|
|
[ [ 'follow' => null, 'name' => null ], [ null, null, null, null, null ] ],
|
2019-11-26 11:18:55 +00:00
|
|
|
[ [ 'follow' => 'f', 'extends' => 'e' ], [ null, 'e', 'f', null, null ] ],
|
|
|
|
[ [ 'group' => 'g', 'name' => 'n' ], [ null, null, null, 'g', 'n' ] ],
|
2019-11-08 14:46:52 +00:00
|
|
|
|
|
|
|
// Combinations of 3 or more attributes
|
|
|
|
[
|
|
|
|
[ 'group' => 'g', 'name' => 'n', 'extends' => 'e', 'dir' => 'rtl' ],
|
2019-11-26 11:18:55 +00:00
|
|
|
[ 'rtl', 'e', null, 'g', 'n' ]
|
2019-11-08 14:46:52 +00:00
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|