wiki.techinc.nl/tests/phpunit/MediaWikiTestCaseTrait.php
Tim Starling df05164822 More flexible deprecation warnings
* Split MWDebug::sendRawDeprecated() from MWDebug::deprecated(). The new
  function can be used to send arbitrary messages to the deprecation
  log, rather than being constrained by the fixed format of
  MWDebug::deprecated().
* Split formatCallerDescription() from sendMessage() to allow the caller
  of sendRawDeprecated() to do its own caller formatting.
* Use the new function in MWLBFactory::logDeprecation()
* In tests, replace the ugly implementation of hideDeprecated() with one
  that works by setting a list of regexes to filter. hideDeprecated()
  now filters deprecation warnings that are a string match to the
  supplied function. filterDeprecated() can be used to filter a regex,
  and is intended to be used to filter warnings sent via
  sendRawDeprecated(). The filter list is reset at the start of each
  test, instead of leaking across tests as before.

Change-Id: I0d0df86db2e61cdd1769426bfa7bad4c2ae5e977
2020-04-22 12:37:22 +10:00

152 lines
4.1 KiB
PHP

<?php
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\MockObject\MockObject;
/**
* For code common to both MediaWikiUnitTestCase and MediaWikiIntegrationTestCase.
*/
trait MediaWikiTestCaseTrait {
/**
* Returns a PHPUnit constraint that matches anything other than a fixed set of values. This can
* be used to whitelist values, e.g.
* $mock->expects( $this->never() )->method( $this->anythingBut( 'foo', 'bar' ) );
* which will throw if any unexpected method is called.
*
* @param mixed ...$values Values that are not matched
* @return Constraint
*/
protected function anythingBut( ...$values ) {
return $this->logicalNot( $this->logicalOr(
...array_map( [ $this, 'matches' ], $values )
) );
}
/**
* Return a PHPUnit mock that is expected to never have any methods called on it.
*
* @param string $type
* @param string[] $allow methods to allow
*
* @return object|MockObject
*/
protected function createNoOpMock( $type, $allow = [] ) {
$mock = $this->createMock( $type );
$mock->expects( $this->never() )->method( $this->anythingBut( '__destruct', ...$allow ) );
return $mock;
}
/**
* Return a PHPUnit mock that is expected to never have any methods called on it.
*
* @param string $type
* @return object
*/
protected function createNoOpAbstractMock( $type ) {
$mock = $this->getMockBuilder( $type )
->disableOriginalConstructor()
->disableOriginalClone()
->disableArgumentCloning()
->disallowMockingUnknownTypes()
->getMockForAbstractClass();
$mock->expects( $this->never() )->method( $this->anythingBut( '__destruct' ) );
return $mock;
}
/**
* Don't throw a warning if $function is deprecated and called later
*
* @since 1.19
*
* @param string $function
*/
public function hideDeprecated( $function ) {
// Construct a regex that will match the message generated by
// wfDeprecated() if it is called for the specified function.
$this->filterDeprecated( '/Use of ' . preg_quote( $function, '/' ) . ' /' );
}
/**
* Don't throw a warning for deprecation messages matching a regex.
*
* @since 1.35
*
* @param string $regex
*/
public function filterDeprecated( $regex ) {
MWDebug::filterDeprecationForTest( $regex );
}
/**
* Check whether file contains given data.
* @param string $fileName
* @param string $actualData
* @param bool $createIfMissing If true, and file does not exist, create it with given data
* and skip the test.
* @param string $msg
* @since 1.30
*/
protected function assertFileContains(
$fileName,
$actualData,
$createIfMissing = false,
$msg = ''
) {
if ( $createIfMissing ) {
if ( !file_exists( $fileName ) ) {
file_put_contents( $fileName, $actualData );
$this->markTestSkipped( "Data file $fileName does not exist" );
}
} else {
$this->assertFileExists( $fileName );
}
$this->assertEquals( file_get_contents( $fileName ), $actualData, $msg );
}
/**
* Assert that two arrays are equal. By default this means that both arrays need to hold
* the same set of values. Using additional arguments, order and associated key can also
* be set as relevant.
*
* @since 1.20
*
* @param array $expected
* @param array $actual
* @param bool $ordered If the order of the values should match
* @param bool $named If the keys should match
*/
protected function assertArrayEquals(
array $expected, array $actual, $ordered = false, $named = false
) {
if ( !$ordered ) {
$this->objectAssociativeSort( $expected );
$this->objectAssociativeSort( $actual );
}
if ( !$named ) {
$expected = array_values( $expected );
$actual = array_values( $actual );
}
call_user_func_array(
[ $this, 'assertEquals' ],
array_merge( [ $expected, $actual ], array_slice( func_get_args(), 4 ) )
);
}
/**
* Does an associative sort that works for objects.
*
* @since 1.20
*
* @param array &$array
*/
protected function objectAssociativeSort( array &$array ) {
uasort(
$array,
function ( $a, $b ) {
return serialize( $a ) <=> serialize( $b );
}
);
}
}