Replace Assert::parameterType with typehints

Bug: T287530
Change-Id: I6060e194339614b53e3a9c036ff3a3ac2e68f8df
This commit is contained in:
TChin 2021-07-30 12:29:14 -04:00
parent 4aea1a348d
commit 077b9af960
20 changed files with 58 additions and 221 deletions

View file

@ -30,7 +30,6 @@ use MediaWiki\Storage\RevisionSlotsUpdate;
use MediaWiki\User\UserIdentity;
use MWException;
use MWTimestamp;
use Wikimedia\Assert\Assert;
/**
* Mutable RevisionRecord implementation, for building new revision entries programmatically.
@ -120,9 +119,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param int $parentId
* @return self
*/
public function setParentId( $parentId ) {
Assert::parameterType( 'integer', $parentId, '$parentId' );
public function setParentId( int $parentId ) {
$this->mParentId = $parentId;
return $this;
@ -246,9 +243,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param string $sha1 SHA1 hash as a base36 string.
* @return self
*/
public function setSha1( $sha1 ) {
Assert::parameterType( 'string', $sha1, '$sha1' );
public function setSha1( string $sha1 ) {
$this->mSha1 = $sha1;
return $this;
@ -264,9 +259,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param int $size nominal size in bogo-bytes
* @return self
*/
public function setSize( $size ) {
Assert::parameterType( 'integer', $size, '$size' );
public function setSize( int $size ) {
$this->mSize = $size;
return $this;
@ -276,9 +269,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param int $visibility
* @return self
*/
public function setVisibility( $visibility ) {
Assert::parameterType( 'integer', $visibility, '$visibility' );
public function setVisibility( int $visibility ) {
$this->mDeleted = $visibility;
return $this;
@ -288,9 +279,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param string $timestamp A timestamp understood by MWTimestamp
* @return self
*/
public function setTimestamp( $timestamp ) {
Assert::parameterType( 'string', $timestamp, '$timestamp' );
public function setTimestamp( string $timestamp ) {
$this->mTimestamp = MWTimestamp::convert( TS_MW, $timestamp );
return $this;
@ -300,9 +289,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param bool $minorEdit
* @return self
*/
public function setMinorEdit( $minorEdit ) {
Assert::parameterType( 'boolean', $minorEdit, '$minorEdit' );
public function setMinorEdit( bool $minorEdit ) {
$this->mMinorEdit = $minorEdit;
return $this;
@ -320,9 +307,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param int $id
* @return self
*/
public function setId( $id ) {
Assert::parameterType( 'integer', $id, '$id' );
public function setId( int $id ) {
$this->mId = $id;
return $this;
@ -344,9 +329,7 @@ class MutableRevisionRecord extends RevisionRecord {
* @param int $pageId
* @return self
*/
public function setPageId( $pageId ) {
Assert::parameterType( 'integer', $pageId, '$pageId' );
public function setPageId( int $pageId ) {
$pageIdBasedOnPage = $this->getArticleId( $this->mPage );
if ( $pageIdBasedOnPage && $pageIdBasedOnPage !== $this->getArticleId( $this->mPage ) ) {
throw new InvalidArgumentException(

View file

@ -27,6 +27,7 @@ use MediaWiki\Page\PageIdentity;
use MediaWiki\Permissions\Authority;
use MediaWiki\User\UserIdentity;
use MWTimestamp;
use stdClass;
use Wikimedia\Assert\Assert;
/**
@ -52,7 +53,7 @@ class RevisionArchiveRecord extends RevisionRecord {
* @param PageIdentity $page The page this RevisionRecord is associated with.
* @param UserIdentity $user
* @param CommentStoreComment $comment
* @param \stdClass $row An archive table row. Use RevisionStore::getArchiveQueryInfo() to build
* @param stdClass $row An archive table row. Use RevisionStore::getArchiveQueryInfo() to build
* a query that yields the required fields.
* @param RevisionSlots $slots The slots of this revision.
* @param false|string $wikiId Relevant wiki or self::LOCAL for the current one.
@ -61,12 +62,11 @@ class RevisionArchiveRecord extends RevisionRecord {
PageIdentity $page,
UserIdentity $user,
CommentStoreComment $comment,
$row,
stdClass $row,
RevisionSlots $slots,
$wikiId = self::LOCAL
) {
parent::__construct( $page, $slots, $wikiId );
Assert::parameterType( \stdClass::class, $row, '$row' );
$timestamp = MWTimestamp::convert( TS_MW, $row->ar_timestamp );
Assert::parameter( is_string( $timestamp ), '$row->rev_timestamp', 'must be a valid timestamp' );

View file

@ -62,6 +62,7 @@ use Psr\Log\NullLogger;
use RecentChange;
use RuntimeException;
use StatusValue;
use stdClass;
use Title;
use TitleFactory;
use Traversable;
@ -1147,15 +1148,12 @@ class RevisionStore
*/
private function loadSlotContent(
SlotRecord $slot,
$blobData = null,
$blobFlags = null,
$blobFormat = null,
$queryFlags = 0
?string $blobData = null,
?string $blobFlags = null,
?string $blobFormat = null,
int $queryFlags = 0
) {
if ( $blobData !== null ) {
Assert::parameterType( 'string', $blobData, '$blobData' );
Assert::parameterType( 'string|null', $blobFlags, '$blobFlags' );
$cacheKey = $slot->hasAddress() ? $slot->getAddress() : null;
if ( $blobFlags === null ) {
@ -1562,8 +1560,8 @@ class RevisionStore
* @see newRevisionFromArchiveRow()
* @since 1.35
*
* @param \stdClass $row
* @param null|\stdClass[]|RevisionSlots $slots
* @param stdClass $row
* @param null|stdClass[]|RevisionSlots $slots
* - Database rows generated from a query based on getSlotsQueryInfo
* with the 'content' flag set. Or
* - RevisionSlots instance
@ -1578,17 +1576,12 @@ class RevisionStore
* @throws MWException
*/
public function newRevisionFromArchiveRowAndSlots(
$row,
stdClass $row,
$slots,
$queryFlags = 0,
PageIdentity $page = null,
int $queryFlags = 0,
?PageIdentity $page = null,
array $overrides = []
) {
Assert::parameterType( \stdClass::class, $row, '$row' );
// check second argument, since the old Revision::newFromArchiveRow had $overrides in that spot.
Assert::parameterType( 'integer', $queryFlags, '$queryFlags' );
if ( !$page && isset( $overrides['title'] ) ) {
if ( !( $overrides['title'] instanceof PageIdentity ) ) {
throw new MWException( 'title field override must contain a PageIdentity object.' );
@ -1642,8 +1635,8 @@ class RevisionStore
/**
* @see newFromRevisionRow()
*
* @param \stdClass $row A database row generated from a query based on getQueryInfo()
* @param null|\stdClass[]|RevisionSlots $slots
* @param stdClass $row A database row generated from a query based on getQueryInfo()
* @param null|stdClass[]|RevisionSlots $slots
* - Database rows generated from a query based on getSlotsQueryInfo
* with the 'content' flag set. Or
* - RevisionSlots instance
@ -1658,14 +1651,12 @@ class RevisionStore
* @see RevisionFactory::newRevisionFromRow
*/
public function newRevisionFromRowAndSlots(
$row,
stdClass $row,
$slots,
$queryFlags = 0,
PageIdentity $page = null,
$fromCache = false
int $queryFlags = 0,
?PageIdentity $page = null,
bool $fromCache = false
) {
Assert::parameterType( \stdClass::class, $row, '$row' );
if ( !$page ) {
if ( isset( $row->page_id )
&& isset( $row->page_namespace )

View file

@ -28,7 +28,6 @@ use MediaWiki\Page\PageIdentity;
use MediaWiki\Permissions\Authority;
use MediaWiki\User\UserIdentity;
use MWTimestamp;
use Wikimedia\Assert\Assert;
/**
* A RevisionRecord representing an existing revision persisted in the revision table.
@ -58,12 +57,11 @@ class RevisionStoreRecord extends RevisionRecord {
PageIdentity $page,
UserIdentity $user,
CommentStoreComment $comment,
$row,
\stdClass $row,
RevisionSlots $slots,
$wikiId = self::LOCAL
) {
parent::__construct( $page, $slots, $wikiId );
Assert::parameterType( \stdClass::class, $row, '$row' );
$this->mId = intval( $row->rev_id );
$this->mPageId = intval( $row->rev_page );
$this->mComment = $comment;

View file

@ -146,9 +146,7 @@ class SlotRecord {
* @param bool $derived
* @return SlotRecord An incomplete proto-slot object, to be used with newSaved() later.
*/
public static function newUnsaved( $role, Content $content, bool $derived = false ) {
Assert::parameterType( 'string', $role, '$role' );
public static function newUnsaved( string $role, Content $content, bool $derived = false ) {
$row = [
'slot_id' => null, // not yet known
'slot_revision_id' => null, // not yet known
@ -182,16 +180,11 @@ class SlotRecord {
* @return SlotRecord If the state of $protoSlot is inappropriate for saving a new revision.
*/
public static function newSaved(
$revisionId,
$contentId,
$contentAddress,
int $revisionId,
?int $contentId,
string $contentAddress,
SlotRecord $protoSlot
) {
Assert::parameterType( 'integer', $revisionId, '$revisionId' );
// TODO once migration is over $contentId must be an integer
Assert::parameterType( 'integer|null', $contentId, '$contentId' );
Assert::parameterType( 'string', $contentAddress, '$contentAddress' );
if ( $protoSlot->hasRevision() && $protoSlot->getRevision() !== $revisionId ) {
throw new LogicException(
"Mismatching revision ID $revisionId: "
@ -256,8 +249,7 @@ class SlotRecord {
* their hash does not contribute to the revision hash, and updates are not included
* in revision history.
*/
public function __construct( $row, $content, bool $derived = false ) {
Assert::parameterType( \stdClass::class, $row, '$row' );
public function __construct( \stdClass $row, $content, bool $derived = false ) {
Assert::parameterType( 'Content|callable', $content, '$content' );
Assert::parameter(

View file

@ -159,8 +159,7 @@ class NameTableStore {
* @throws NameTableAccessException
* @return int
*/
public function acquireId( $name ) {
Assert::parameterType( 'string', $name, '$name' );
public function acquireId( string $name ) {
$name = $this->normalizeName( $name );
$table = $this->getTableFromCachesOrReplica();
@ -249,8 +248,7 @@ class NameTableStore {
* @throws NameTableAccessException The name does not exist
* @return int Id
*/
public function getId( $name ) {
Assert::parameterType( 'string', $name, '$name' );
public function getId( string $name ) {
$name = $this->normalizeName( $name );
$table = $this->getTableFromCachesOrReplica();
@ -274,9 +272,7 @@ class NameTableStore {
* @throws NameTableAccessException The id does not exist
* @return string name
*/
public function getName( $id ) {
Assert::parameterType( 'integer', $id, '$id' );
public function getName( int $id ) {
$table = $this->getTableFromCachesOrReplica();
if ( array_key_exists( $id, $table ) ) {
return $table[$id];
@ -394,8 +390,7 @@ class NameTableStore {
* @param string $name
* @return int|null int if we know the ID, null if we don't
*/
private function store( $name ) {
Assert::parameterType( 'string', $name, '$name' );
private function store( string $name ) {
Assert::parameter( $name !== '', '$name', 'should not be an empty string' );
// Note: this is only called internally so normalization of $name has already occurred.

View file

@ -571,8 +571,7 @@ class PageUpdater {
* @param string $tag
* @return $this
*/
public function addTag( $tag ) {
Assert::parameterType( 'string', $tag, '$tag' );
public function addTag( string $tag ) {
$this->tags[] = trim( $tag );
return $this;
}
@ -738,11 +737,7 @@ class PageUpdater {
* @throws MWException
* @throws RuntimeException
*/
public function saveRevision( CommentStoreComment $summary, $flags = 0 ) {
// Defend against mistakes caused by differences with the
// signature of WikiPage::doEditContent.
Assert::parameterType( 'integer', $flags, '$flags' );
public function saveRevision( CommentStoreComment $summary, int $flags = 0 ) {
if ( $this->wasCommitted() ) {
throw new RuntimeException(
'saveRevision() or updateRevision() has already been called on this PageUpdater!'

View file

@ -127,9 +127,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
/**
* @param int $cacheExpiry time for which blobs can be cached, in seconds
*/
public function setCacheExpiry( $cacheExpiry ) {
Assert::parameterType( 'integer', $cacheExpiry, '$cacheExpiry' );
public function setCacheExpiry( int $cacheExpiry ) {
$this->cacheExpiry = $cacheExpiry;
}
@ -172,9 +170,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
* @param string $legacyEncoding The legacy encoding to assume for blobs that are
* not marked as utf8.
*/
public function setLegacyEncoding( $legacyEncoding ) {
Assert::parameterType( 'string', $legacyEncoding, '$legacyEncoding' );
public function setLegacyEncoding( string $legacyEncoding ) {
$this->legacyEncoding = $legacyEncoding;
}
@ -188,9 +184,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
/**
* @param bool $useExternalStore Whether to use the ExternalStore mechanism for storing blobs.
*/
public function setUseExternalStore( $useExternalStore ) {
Assert::parameterType( 'boolean', $useExternalStore, '$useExternalStore' );
public function setUseExternalStore( bool $useExternalStore ) {
$this->useExternalStore = $useExternalStore;
}
@ -578,10 +572,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
*
* @return string|bool Decompressed text, or false on failure
*/
public function decompressData( $blob, array $blobFlags ) {
// Revision::decompressRevisionText accepted false here, so defend against that
Assert::parameterType( 'string', $blob, '$blob' );
public function decompressData( string $blob, array $blobFlags ) {
if ( in_array( 'error', $blobFlags ) ) {
// Error row, return false
return false;

View file

@ -136,10 +136,7 @@ class TextSlotDiffRenderer extends SlotDiffRenderer {
* @param string $newText
* @return string HTML, one or more <tr> tags.
*/
public function getTextDiff( $oldText, $newText ) {
Assert::parameterType( 'string', $oldText, '$oldText' );
Assert::parameterType( 'string', $newText, '$newText' );
public function getTextDiff( string $oldText, string $newText ) {
$diff = function () use ( $oldText, $newText ) {
$time = microtime( true );

View file

@ -7,7 +7,6 @@ use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Wikimedia\Assert\Assert;
/**
* @ingroup ExternalStorage
@ -31,11 +30,9 @@ class ExternalStoreFactory implements LoggerAwareInterface {
public function __construct(
array $externalStores,
array $defaultStores,
$localDomainId,
string $localDomainId,
LoggerInterface $logger = null
) {
Assert::parameterType( 'string', $localDomainId, '$localDomainId' );
$this->protocols = array_map( 'strtolower', $externalStores );
$this->writeBaseUrls = $defaultStores;
$this->localDomainId = $localDomainId;

View file

@ -58,10 +58,9 @@ class MapCacheLRU implements ExpirationAwareness, Serializable {
/**
* @param int $maxKeys Maximum number of entries allowed (min 1)
* @throws Exception When $maxKeys is not an int or not above zero
* @throws Exception When $maxKeys is not above zero
*/
public function __construct( $maxKeys ) {
Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
public function __construct( int $maxKeys ) {
Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
$this->maxCacheKeys = $maxKeys;
@ -313,11 +312,10 @@ class MapCacheLRU implements ExpirationAwareness, Serializable {
*
* @param int $maxKeys Maximum number of entries allowed (min 1)
* @return void
* @throws Exception When $maxKeys is not an int or not above zero
* @throws Exception When $maxKeys is not above zero
* @since 1.32
*/
public function setMaxSize( $maxKeys ) {
Assert::parameterType( 'integer', $maxKeys, '$maxKeys' );
public function setMaxSize( int $maxKeys ) {
Assert::parameter( $maxKeys > 0, '$maxKeys', 'must be above zero' );
$this->maxCacheKeys = $maxKeys;

View file

@ -117,8 +117,7 @@ class GlobalIdGenerator {
* @return string Number
* @throws RuntimeException
*/
public function newTimestampedUID88( $base = 10 ) {
Assert::parameterType( 'integer', $base, '$base' );
public function newTimestampedUID88( int $base = 10 ) {
Assert::parameter( $base <= 36, '$base', 'must be <= 36' );
Assert::parameter( $base >= 2, '$base', 'must be >= 2' );
@ -164,8 +163,7 @@ class GlobalIdGenerator {
* @return string Number
* @throws RuntimeException
*/
public function newTimestampedUID128( $base = 10 ) {
Assert::parameterType( 'integer', $base, '$base' );
public function newTimestampedUID128( int $base = 10 ) {
Assert::parameter( $base <= 36, '$base', 'must be <= 36' );
Assert::parameter( $base >= 2, '$base', 'must be >= 2' );

View file

@ -25,7 +25,6 @@ use MediaWiki\MediaWikiServices;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Revision\SlotRecord;
use Wikimedia\Assert\Assert;
use Wikimedia\Minify\CSSMin;
use Wikimedia\Rdbms\Database;
use Wikimedia\Rdbms\IDatabase;
@ -562,12 +561,10 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
PageIdentity $page,
?RevisionRecord $old,
?RevisionRecord $new,
$domain
string $domain
) {
static $models = [ CONTENT_MODEL_CSS, CONTENT_MODEL_JAVASCRIPT ];
Assert::parameterType( 'string', $domain, '$domain' );
$purge = false;
// TODO: MCR: differentiate between page functionality and content model!
// Not all pages containing CSS or JS have to be modules! [PageType]

View file

@ -21,8 +21,6 @@
*/
use MediaWiki\MediaWikiServices;
use Wikimedia\Assert\Assert;
use Wikimedia\Assert\ParameterTypeException;
/**
* Represents a "user group membership" -- a specific instance of a user belonging
@ -52,29 +50,13 @@ class UserGroupMembership {
* @param string|null $group The internal group name
* @param string|null $expiry Timestamp of expiry in TS_MW format, or null if no expiry
*/
public function __construct( $userId = 0, $group = null, $expiry = null ) {
self::assertValidSpec( $userId, $group, $expiry );
$this->userId = (int)$userId;
public function __construct( int $userId = 0, ?string $group = null, ?string $expiry = null ) {
$this->userId = $userId;
$this->group = $group;
$this->expiry = $expiry ?: null;
$this->expired = $expiry ? wfTimestampNow() > $expiry : false;
}
/**
* Asserts that the given parameters could be used to construct a UserGroupMembership object
*
* @param int $userId
* @param string|null $group
* @param string|null $expiry
*
* @throws ParameterTypeException
*/
private static function assertValidSpec( $userId, $group, $expiry ) {
Assert::parameterType( 'integer', $userId, '$userId' );
Assert::parameterType( [ 'string', 'null' ], $group, '$group' );
Assert::parameterType( [ 'string', 'null' ], $expiry, '$expiry' );
}
/**
* @return int
*/

View file

@ -58,7 +58,7 @@ class UserIdentityValue implements UserIdentity {
* @param string $name user name
* @param string|false $wikiId wiki ID or self::LOCAL for the local wiki
*/
public function __construct( $id, $name, $wikiId = self::LOCAL ) {
public function __construct( int $id, string $name, $wikiId = self::LOCAL ) {
if ( is_int( $wikiId ) ) {
// Handle old signature: ( $id, $name, $actor, $wikiId )
$args = func_get_args();
@ -74,8 +74,6 @@ class UserIdentityValue implements UserIdentity {
}
}
Assert::parameterType( 'integer', $id, '$id' );
Assert::parameterType( 'string', $name, '$name' );
$this->assertWikiIdParam( $wikiId );
$this->id = $id;

View file

@ -209,6 +209,8 @@ class RevisionArchiveRecordTest extends MediaWikiIntegrationTestCase {
'ar_sha1' => $slots->computeSha1(),
];
$row = $protoRow;
yield 'mismatching wiki ID' => [
new PageIdentityValue(
$title->getArticleID(),
@ -218,26 +220,12 @@ class RevisionArchiveRecordTest extends MediaWikiIntegrationTestCase {
),
$user,
$comment,
'not a row',
(object)$row,
$slots,
'acmewiki',
PreconditionException::class
];
yield 'not a row' => [
new PageIdentityValue(
$title->getArticleID(),
$title->getNamespace(),
$title->getDBkey(),
'acmewiki'
),
$user,
$comment,
'not a row',
$slots,
'acmewiki'
];
$row = $protoRow;
$row['ar_timestamp'] = 'kittens';

View file

@ -236,15 +236,6 @@ class RevisionStoreRecordTest extends MediaWikiIntegrationTestCase {
'page_latest' => '18',
];
yield 'not a row' => [
new PageIdentityValue( 17, NS_MAIN, 'Dummy', 'acmewiki' ),
$user,
$comment,
'not a row',
$slots,
'acmewiki'
];
$row = $protoRow;
$row['rev_page'] = 99;

View file

@ -104,9 +104,6 @@ class SlotRecordTest extends \MediaWikiIntegrationTestCase {
}
public function provideInvalidConstruction() {
yield 'both null' => [ null, null ];
yield 'null row' => [ null, new WikitextContent( 'A' ) ];
yield 'array row' => [ [], new WikitextContent( 'A' ) ];
yield 'empty row' => [ (object)[], new WikitextContent( 'A' ) ];
yield 'null content' => [ (object)[], null ];
}
@ -298,27 +295,6 @@ class SlotRecordTest extends \MediaWikiIntegrationTestCase {
SlotRecord::newSaved( $revisionId, $contentId, $contentAddress, $protoSlot );
}
public function provideNewSaved_InvalidArgumentException() {
$unsaved = SlotRecord::newUnsaved( SlotRecord::MAIN, new WikitextContent( 'A' ) );
yield 'bad revision id' => [ 'xyzzy', 5, 'address', $unsaved ];
yield 'bad content id' => [ 7, 'xyzzy', 'address', $unsaved ];
yield 'bad content address' => [ 7, 5, 77, $unsaved ];
}
/**
* @dataProvider provideNewSaved_InvalidArgumentException
*/
public function testNewSaved_InvalidArgumentException(
$revisionId,
$contentId,
$contentAddress,
SlotRecord $protoSlot
) {
$this->expectException( InvalidArgumentException::class );
SlotRecord::newSaved( $revisionId, $contentId, $contentAddress, $protoSlot );
}
public function provideHasSameContent() {
$fail = function () {
self::fail( 'There should be no need to actually load the content.' );

View file

@ -176,16 +176,6 @@ class SqlBlobStoreTest extends MediaWikiIntegrationTestCase {
);
}
/**
* @covers \MediaWiki\Storage\SqlBlobStore::decompressData
*/
public function testDecompressData_InvalidArgumentException() {
$store = $this->getBlobStore();
$this->expectException( InvalidArgumentException::class );
$store->decompressData( false, [] );
}
/**
* @covers \MediaWiki\Storage\SqlBlobStore::compressData
*/

View file

@ -1,7 +1,5 @@
<?php
use Wikimedia\Assert\ParameterTypeException;
class UserGroupMembershipTest extends MediaWikiIntegrationTestCase {
protected function setUp(): void {
@ -19,24 +17,6 @@ class UserGroupMembershipTest extends MediaWikiIntegrationTestCase {
] );
}
public function provideInstantiationValidationErrors() {
return [
[ 'A', null, null, 'Bad value for parameter $userId: must be a integer' ],
[ 1, 1, null, 'Bad value for parameter $group: must be a string' ],
[ 1, null, 1, 'Bad value for parameter $expiry: must be a string' ],
];
}
/**
* @dataProvider provideInstantiationValidationErrors
* @covers UserGroupMembership
*/
public function testInstantiationValidationErrors( $userId, $group, $expiry, $exception ) {
$this->expectExceptionMessage( $exception );
$this->expectException( ParameterTypeException::class );
$ugm = new UserGroupMembership( $userId, $group, $expiry );
}
public function provideInstantiationValidation() {
return [
[ 1, null, null, 1, null, null ],