//after dropping HHVM
// approximate error count: 110
"PhanParamTooMany", // False positives with variargs. Unsuppress after dropping HHVM
-
- // approximate error count: 45
- "PhanTypeMismatchArgument",
] );
// This helps a lot in discovering bad code, but unfortunately it will always fail for
$out->showErrorPage(
'modeleditnotsupported-title',
'modeleditnotsupported-text',
- $modelName
+ [ $modelName ]
);
return false;
}
* @param ServiceOptions|null $options
* @param ILoadBalancer|null $loadBalancer
* @param NamespaceInfo|null $nsInfo
- * @param WatchedItemStore|null $watchedItems
+ * @param WatchedItemStoreInterface|null $watchedItems
* @param PermissionManager|null $permMgr
*/
public function __construct(
* @param object[]|IResultWrapper $slotRows
* @param int $queryFlags
* @param Title $title
+ * @param array|null $slotContents a map from blobAddress to slot
+ * content blob or Content object.
*
* @return SlotRecord[]
*/
- private function constructSlotRecords( $revId, $slotRows, $queryFlags, Title $title ) {
+ private function constructSlotRecords(
+ $revId,
+ $slotRows,
+ $queryFlags,
+ Title $title,
+ $slotContents = null
+ ) {
$slots = [];
foreach ( $slotRows as $row ) {
= $this->emulateContentId( intval( $row->rev_text_id ) );
}
- $contentCallback = function ( SlotRecord $slot ) use ( $queryFlags ) {
- return $this->loadSlotContent( $slot, null, null, null, $queryFlags );
+ $contentCallback = function ( SlotRecord $slot ) use ( $slotContents, $queryFlags ) {
+ $blob = null;
+ if ( isset( $slotContents[$slot->getAddress()] ) ) {
+ $blob = $slotContents[$slot->getAddress()];
+ if ( $blob instanceof Content ) {
+ return $blob;
+ }
+ }
+ return $this->loadSlotContent( $slot, $blob, null, null, $queryFlags );
};
$slots[$row->role_name] = new SlotRecord( $row, $contentCallback );
/**
* @param object $row A database row generated from a query based on getQueryInfo()
- * @param null|object[] $slotRows Database rows generated from a query based on
- * getSlotsQueryInfo with the 'content' flag set.
+ * @param null|object[]|RevisionSlots $slots
+ * - Database rows generated from a query based on getSlotsQueryInfo
+ * with the 'content' flag set. Or
+ * - RevisionSlots instance
* @param int $queryFlags
* @param Title|null $title
* @param bool $fromCache if true, the returned RevisionRecord will ensure that no stale
* @see RevisionFactory::newRevisionFromRow
*
* MCR migration note: this replaces Revision::newFromRow
- *
*/
public function newRevisionFromRowAndSlots(
$row,
- $slotRows,
+ $slots,
$queryFlags = 0,
Title $title = null,
$fromCache = false
// Legacy because $row may have come from self::selectFields()
$comment = $this->commentStore->getCommentLegacy( $db, 'rev_comment', $row, true );
- $slots = $this->newRevisionSlots( $row->rev_id, $row, $slotRows, $queryFlags, $title );
+ if ( !( $slots instanceof RevisionSlots ) ) {
+ $slots = $this->newRevisionSlots( $row->rev_id, $row, $slots, $queryFlags, $title );
+ }
// If this is a cached row, instantiate a cache-aware revision class to avoid stale data.
if ( $fromCache ) {
* loaded immediately. Supports falsy or truthy value as well
* as an explicit list of slot role names.
* 'content'- whether the actual content of the slots should be
- * preloaded. TODO: no supported yet.
+ * preloaded.
* @param int $queryFlags
* @param Title|null $title
* @return StatusValue a status with a RevisionRecord[] of successfully fetched revisions
}, $options['slots'] );
}
- // TODO: Support optional fetching of the content
- $queryInfo = self::getSlotsQueryInfo( [ 'content' ] );
+ // We need to set the `content` flag because newRevisionFromRowAndSlots requires content
+ // metadata to be loaded.
+ $slotQueryInfo = self::getSlotsQueryInfo( [ 'content' ] );
$db = $this->getDBConnectionRefForQueryFlags( $queryFlags );
$slotRows = $db->select(
- $queryInfo['tables'],
- $queryInfo['fields'],
+ $slotQueryInfo['tables'],
+ $slotQueryInfo['fields'],
$slotQueryConds,
__METHOD__,
[],
- $queryInfo['joins']
+ $slotQueryInfo['joins']
);
$slotRowsByRevId = [];
foreach ( $slotRows as $slotRow ) {
$slotRowsByRevId[$slotRow->slot_revision_id][] = $slotRow;
}
+
+ $slotContents = null;
+ if ( $options['content'] ?? false ) {
+ $blobAddresses = [];
+ foreach ( $slotRows as $slotRow ) {
+ $blobAddresses[] = $slotRow->content_address;
+ }
+ $slotContentFetchStatus = $this->blobStore
+ ->getBlobBatch( $blobAddresses, $queryFlags );
+ foreach ( $slotContentFetchStatus->getErrors() as $error ) {
+ $result->warning( $error['message'], ...$error['params'] );
+ }
+ $slotContents = $slotContentFetchStatus->getValue();
+ }
+
$result->setResult( true, array_map( function ( $row ) use
- ( $slotRowsByRevId, $queryFlags, $titlesByPageId, $result ) {
+ ( $slotRowsByRevId, $queryFlags, $titlesByPageId, $slotContents, $result ) {
if ( !isset( $slotRowsByRevId[$row->rev_id] ) ) {
$result->warning(
'internalerror',
try {
return $this->newRevisionFromRowAndSlots(
$row,
- $slotRowsByRevId[$row->rev_id],
+ new RevisionSlots(
+ $this->constructSlotRecords(
+ $row->rev_id,
+ $slotRowsByRevId[$row->rev_id],
+ $queryFlags,
+ $titlesByPageId[$row->rev_page],
+ $slotContents
+ )
+ ),
$queryFlags,
$titlesByPageId[$row->rev_page]
);
*
* @see self::getLocalURL for the arguments.
* @see wfExpandUrl
- * @param string|string[] $query
+ * @param string|array $query
* @param string|string[]|bool $query2
* @param string|int|null $proto Protocol type to use in URL
* @return string The URL
* valid to link, locally, to the current Title.
* @see self::newFromText to produce a Title object.
*
- * @param string|string[] $query An optional query string,
+ * @param string|array $query An optional query string,
* not used for interwiki links. Can be specified as an associative array as well,
* e.g., [ 'action' => 'edit' ] (keys and values will be URL-escaped).
* Some query patterns will trigger various shorturl path replacements.
* protocol-relative, the URL will be expanded to http://
*
* @see self::getLocalURL for the arguments.
- * @param string|string[] $query
+ * @param string|array $query
* @param string|bool $query2 Deprecated
* @return string The URL
*/
* NOTE: Unlike getInternalURL(), the canonical URL includes the fragment
*
* @see self::getLocalURL for the arguments.
- * @param string|string[] $query
+ * @param string|array $query
* @param string|bool $query2 Deprecated
* @return string The URL
* @since 1.18
'integeroutofrange',
[ 'min' => $min, 'max' => $max, 'botMax' => $botMax ?: $max ]
);
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->warnOrDie( $msg, $enforceLimits );
$value = $min;
}
'integeroutofrange',
[ 'min' => $min, 'max' => $max, 'botMax' => $botMax ?: $max ]
);
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->warnOrDie( $msg, $enforceLimits );
$value = $botMax;
}
'integeroutofrange',
[ 'min' => $min, 'max' => $max, 'botMax' => $botMax ?: $max ]
);
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->warnOrDie( $msg, $enforceLimits );
$value = $max;
}
*/
public function dieWithException( $exception, array $options = [] ) {
$this->dieWithError(
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->getErrorFormatter()->getMessageFromException( $exception, $options )
);
}
if ( $m ) {
$m = new ApiHelpParamValueMessage(
$value,
+ // @phan-suppress-next-line PhanTypeMismatchArgument
[ $m->getKey(), 'api-help-param-no-description' ],
$m->getParams(),
isset( $deprecatedValues[$value] )
*/
public function formatException( $exception, array $options = [] ) {
return $this->formatMessage(
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->getMessageFromException( $exception, $options ),
$options['format'] ?? null
);
// T71222: MariaDB's optimizer, at least 10.1.37 and .38, likes to choose a wildly bad plan for
// some reason for this code path. Tell it not to use the wrong index it wants to pick.
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->addOption( 'IGNORE INDEX', [ 'logging' => [ 'times' ] ] );
}
$valid = RecentChange::newFromId( $id );
if ( $valid && $this->getPermissionManager()->isBlockedFrom( $user, $valid->getTitle() ) ) {
$idResult['status'] = 'error';
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create(
'apierror-blocked',
'blocked',
$this->getPermissionManager()->isBlockedFrom( $user, $valid->getPageAsLinkTarget() )
) {
$idResult['status'] = 'error';
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$idResult += $this->getErrorFormatter()->formatMessage( ApiMessage::create(
'apierror-blocked',
'blocked',
}
ApiResult::setIndexedTagName( $details, 'detail' );
$msg->setApiData( $msg->getApiData() + [ 'details' => $details ] );
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->dieWithError( $msg );
break;
"authors": [
"Zygimantus",
"Eitvys200",
- "Hugo.arg"
+ "Hugo.arg",
+ "Homo"
]
},
"apihelp-main-param-action": "Kurį veiksmą atlikti.",
"apihelp-createaccount-summary": "Kurti naują vartotojo paskyrą.",
"apihelp-delete-summary": "Ištrinti puslapį.",
"apihelp-delete-param-watch": "Pridėti puslapį prie dabartinio vartotojo stebimųjų sąrašo.",
- "apihelp-delete-param-unwatch": "Pašalinti puslapį iš dabartinio vartotojo stebimųjų sąrašo.",
+ "apihelp-delete-param-unwatch": "Pašalinti puslapį iš dabartinio naudotojo stebimųjų sąrašo.",
"apihelp-delete-example-simple": "Ištrinti <kbd>Main Page</kbd>.",
"apihelp-delete-example-reason": "Ištrinti <kbd>Main Page</kbd> su priežastimi <kbd>Preparing for move</kbd>.",
"apihelp-disabled-summary": "Šis modulis buvo išjungtas.",
"apihelp-edit-param-createonly": "Neredaguoti puslapio jei jis jau egzistuoja.",
"apihelp-edit-param-nocreate": "Parodyti klaidą, jei puslapis neegzistuoja.",
"apihelp-edit-param-watch": "Pridėti puslapį į dabartinio vartotojo stebimųjų sąrašą.",
- "apihelp-edit-param-unwatch": "Pašalinti puslapį iš dabartinio vartotojo stebimųjų sąrašo.",
+ "apihelp-edit-param-unwatch": "Pašalinti puslapį iš dabartinio naudotojo stebimųjų sąrašo.",
"apihelp-edit-param-redirect": "Automatiškai išspręsti peradresavimus.",
"apihelp-edit-param-contentmodel": "Naujam turiniui taikomas turinio modelis.",
"apihelp-edit-example-edit": "Redaguoti puslapį.",
"apihelp-move-param-movetalk": "Pervadinti aptarimo puslapį, jei jis egzistuoja.",
"apihelp-move-param-noredirect": "Nekurti nukreipimo.",
"apihelp-move-param-watch": "Pridėti puslapį ir nukreipimą į dabartinio vartotojo stebimųjų sąrašą.",
- "apihelp-move-param-unwatch": "Pašalinti puslapį ir nukreipimą iš dabartinio vartotojo stebimųjų sąrašo.",
+ "apihelp-move-param-unwatch": "Pašalinti puslapį ir nukreipimą iš dabartinio naudotojo stebimųjų sąrašo.",
"apihelp-move-param-ignorewarnings": "Ignuoruoti bet kokius įspėjimus.",
"apihelp-move-example-move": "Perkelti <kbd>Badtitle</kbd> į <kbd>Goodtitle</kbd> nepaliekant nukreipimo.",
"apihelp-opensearch-summary": "Ieškoti viki naudojant OpenSearch protokolą.",
"apihelp-query+watchlist-paramvalue-type-new": "Puslapio sukūrimai.",
"apihelp-query+watchlist-paramvalue-type-log": "Žurnalo įrašai.",
"apihelp-resetpassword-param-user": "Iš naujo nustatomas vartotojas.",
- "apihelp-resetpassword-param-email": "Iš naujo nustatomo vartotojo el. pašto adresas.",
+ "apihelp-resetpassword-param-email": "Iš naujo nustatomo naudotojo el. pašto adresas.",
"apihelp-setpagelanguage-summary": "Keisti puslapio kalbą.",
"apihelp-setpagelanguage-param-reason": "Keitimo priežastis.",
"apihelp-stashedit-param-title": "Puslapio pavadinimas buvo redaguotas.",
// TODO: Improve on simply tracking the first trackable block (T225654)
foreach ( $block->getOriginalBlocks() as $originalBlock ) {
if ( $this->shouldTrackBlockWithCookie( $originalBlock, $isAnon ) ) {
+ '@phan-var DatabaseBlock $originalBlock';
$this->setBlockCookie( $originalBlock, $response );
return;
}
}
} else {
if ( $this->shouldTrackBlockWithCookie( $block, $isAnon ) ) {
+ '@phan-var DatabaseBlock $block';
$this->setBlockCookie( $block, $response );
}
}
* @param string &$s HTML to update
* @param Title $title
* @param string $logtype
+ * @param bool $useParentheses (optional) Wrap log entry in parentheses where needed
*/
- public function insertLog( &$s, $title, $logtype ) {
+ public function insertLog( &$s, $title, $logtype, $useParentheses = true ) {
$page = new LogPage( $logtype );
$logname = $page->getName()->setContext( $this->getContext() )->text();
- $s .= Html::rawElement( 'span', [
- 'class' => 'mw-changeslist-links'
- ], $this->linkRenderer->makeKnownLink( $title, $logname ) );
+ $link = $this->linkRenderer->makeKnownLink( $title, $logname, [
+ 'class' => $useParentheses ? '' : 'mw-changeslist-links'
+ ] );
+ if ( $useParentheses ) {
+ $s .= $this->msg( 'parentheses' )->rawParams(
+ $link
+ )->escaped();
+ } else {
+ $s .= $link;
+ }
}
/**
*/
public function insertComment( $rc ) {
if ( $this->isDeleted( $rc, RevisionRecord::DELETED_COMMENT ) ) {
- return ' <span class="history-deleted">' .
+ return ' <span class="history-deleted comment">' .
$this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
} else {
return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle(),
if ( $rc->mAttribs['rc_log_type'] ) {
$logtitle = SpecialPage::getTitleFor( 'Log', $rc->mAttribs['rc_log_type'] );
- $this->insertLog( $html, $logtitle, $rc->mAttribs['rc_log_type'] );
+ $this->insertLog( $html, $logtitle, $rc->mAttribs['rc_log_type'], false );
$flags = $this->recentChangesFlags( [ 'unpatrolled' => $unpatrolled,
'bot' => $rc->mAttribs['rc_bot'] ], '' );
if ( $flags !== '' ) {
list( $name, $htmlubpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
resolveAlias( $rc->mAttribs['rc_title'] );
if ( $name == 'Log' ) {
- $this->insertLog( $html, $rc->getTitle(), $htmlubpage );
+ $this->insertLog( $html, $rc->getTitle(), $htmlubpage, false );
}
// Regular entries
} else {
function pageCount() {
if ( !isset( $this->pageCount ) ) {
// @FIXME: callers expect File objects
+ // @phan-suppress-next-line PhanTypeMismatchArgument
if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
+ // @phan-suppress-next-line PhanTypeMismatchArgument
$this->pageCount = $this->handler->pageCount( $this );
} else {
$this->pageCount = false;
* Automatically does validation that the title is valid,
* as well as autocompletion if using the OOUI display format.
*
- * Note: Forms using GET requests will need to make sure the title value is not
- * an empty string.
- *
* Optional parameters:
* 'namespace' - Namespace the page must be in
* 'relative' - If true and 'namespace' given, strip/add the namespace from/to the title as needed
}
public function validate( $value, $alldata ) {
- if ( $this->mParent->getMethod() === 'get' && $value === '' ) {
- // If the form is a GET form and has no value, assume it hasn't been
- // submitted yet, and skip validation
- // TODO This doesn't look right, we should be able to tell the difference
- // between "not submitted" (null) and "submitted but empty" (empty string).
- return parent::validate( $value, $alldata );
- }
-
// Default value (from getDefault()) is null, which breaks Title::newFromTextThrow() below
if ( $value === null ) {
$value = '';
* Implements a text input field for user names.
* Automatically auto-completes if using the OOUI display format.
*
- * FIXME: Does not work for forms that support GET requests.
- *
* Optional parameters:
* 'exists' - Whether to validate that the user already exists
* 'ipallowed' - Whether an IP adress is interpreted as "valid"
* - originalRequest Information about the original request (as a WebRequest object or
* an associative array with 'ip' and 'userAgent').
* @codingStandardsIgnoreStart
- * @phan-param array{timeout?:int,connectTimeout?:int,postData?:array,proxy?:string,noProxy?:bool,sslVerifyHost?:bool,sslVerifyCert?:bool,caInfo?:string,maxRedirects?:int,followRedirects?:bool,userAgent?:string,logger?:\Psr\Logger\LoggerInterface,username?:string,password?:string,originalRequest?:WebRequest|array{ip:string,userAgent:string}} $options
+ * @phan-param array{timeout?:int,connectTimeout?:int,postData?:array,proxy?:string,noProxy?:bool,sslVerifyHost?:bool,sslVerifyCert?:bool,caInfo?:string,maxRedirects?:int,followRedirects?:bool,userAgent?:string,method?:string,logger?:\Psr\Log\LoggerInterface,username?:string,password?:string,originalRequest?:WebRequest|array{ip:string,userAgent:string}} $options
* @codingStandardsIgnoreEnd
* @param string $caller The method making this request, for profiling
* @throws RuntimeException
/** @var bool */
private $mNoUpdates = false;
- /** @var Config $config */
+ /**
+ * @deprecated since 1.31, along with self::downloadSource()
+ * @var Config $config
+ */
private $config;
+ /**
+ * @param Config $config Deprecated since 1.31, along with self::downloadSource(). Just pass an
+ * empty HashConfig.
+ */
public function __construct( Config $config ) {
$this->config = $config;
}
'headers' => array_merge(
$mutableHeaders,
[
- 'content-length' => strlen( $params['content'] ),
'etag' => md5( $params['content'] ),
+ 'content-length' => strlen( $params['content'] ),
'x-object-meta-sha1base36' =>
Wikimedia\base_convert( sha1( $params['content'] ), 16, 36, 31 )
]
return $status;
}
+ // Open a handle to the source file so that it can be streamed. The size and hash
+ // will be computed using the handle. In the off chance that the source file changes
+ // during this operation, the PUT will fail due to an ETag mismatch and be aborted.
AtEase::suppressWarnings();
- $sha1Base16 = sha1_file( $params['src'] );
+ $srcHandle = fopen( $params['src'], 'rb' );
AtEase::restoreWarnings();
- if ( $sha1Base16 === false ) { // source doesn't exist?
- $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
+ if ( $srcHandle === false ) { // source doesn't exist?
+ $status->fatal( 'backend-fail-notexists', $params['src'] );
return $status;
}
- $handle = fopen( $params['src'], 'rb' );
- if ( $handle === false ) { // source doesn't exist?
- $status->fatal( 'backend-fail-store', $params['src'], $params['dst'] );
+ // Compute the MD5 and SHA-1 hashes in one pass
+ $srcSize = fstat( $srcHandle )['size'];
+ $md5Context = hash_init( 'md5' );
+ $sha1Context = hash_init( 'sha1' );
+ $hashDigestSize = 0;
+ while ( !feof( $srcHandle ) ) {
+ $buffer = (string)fread( $srcHandle, 131072 ); // 128 KiB
+ hash_update( $md5Context, $buffer );
+ hash_update( $sha1Context, $buffer );
+ $hashDigestSize += strlen( $buffer );
+ }
+ // Reset the handle back to the beginning so that it can be streamed
+ rewind( $srcHandle );
+
+ if ( $hashDigestSize !== $srcSize ) {
+ $status->fatal( 'backend-fail-hash', $params['src'] );
return $status;
}
'headers' => array_merge(
$mutableHeaders,
[
- 'content-length' => fstat( $handle )['size'],
- 'etag' => md5_file( $params['src'] ),
- 'x-object-meta-sha1base36' => Wikimedia\base_convert( $sha1Base16, 16, 36, 31 )
+ 'content-length' => $srcSize,
+ 'etag' => hash_final( $md5Context ),
+ 'x-object-meta-sha1base36' =>
+ Wikimedia\base_convert( hash_final( $sha1Context ), 16, 36, 31 )
]
),
- 'body' => $handle // resource
+ 'body' => $srcHandle // resource
] ];
$method = __METHOD__;
};
$opHandle = new SwiftFileOpHandle( $this, $handler, $reqs );
- $opHandle->resourcesToClose[] = $handle;
+ $opHandle->resourcesToClose[] = $srcHandle;
if ( !empty( $params['async'] ) ) { // deferred
$status->value = $opHandle;
$this->mLogEventsList = $list;
$this->limitType( $types ); // also excludes hidden types
+ $this->limitLogId( $logId );
+ $this->limitFilterTypes();
$this->limitPerformer( $performer );
$this->limitTitle( $title, $pattern );
$this->limitAction( $action );
$this->getDateCond( $year, $month, $day );
$this->mTagFilter = $tagFilter;
- $this->limitLogId( $logId );
$this->mDb = wfGetDB( DB_REPLICA, 'logpager' );
}
return $query;
}
- // Call ONLY after calling $this->limitType() already!
+ private function limitFilterTypes() {
+ if ( $this->hasEqualsClause( 'log_id' ) ) { // T220834
+ return;
+ }
+ $filterTypes = $this->getFilterParams();
+ foreach ( $filterTypes as $type => $hide ) {
+ if ( $hide ) {
+ $this->mConds[] = 'log_type != ' . $this->mDb->addQuotes( $type );
+ }
+ }
+ }
+
public function getFilterParams() {
global $wgFilterLogTypes;
$filters = [];
}
$filters[$type] = $hide;
- if ( $hide ) {
- $this->mConds[] = 'log_type != ' . $this->mDb->addQuotes( $type );
- }
}
return $filters;
Wikimedia\restoreWarnings();
return Status::newFatal( 'pear-mail-error', $mail_object->getMessage() );
}
+ '@phan-var Mail_smtp $mail_object';
wfDebug( "Sending mail via PEAR::Mail\n" );
use NamespaceInfo;
use RepoGroup;
use Title;
-use WatchedItemStore;
use WatchedItemStoreInterface;
use Wikimedia\Rdbms\ILoadBalancer;
/** @var NamespaceInfo */
private $nsInfo;
- /** @var WatchedItemStore */
+ /** @var WatchedItemStoreInterface */
private $watchedItems;
/** @var PermissionManager */
} else {
$accum = [];
}
+ // @phan-suppress-next-line PhanTypeMismatchArgument
parent::__construct( $accum );
}
}
$pathTags = $siteElement->getElementsByTagName( 'path' );
for ( $i = 0; $i < $pathTags->length; $i++ ) {
$pathElement = $pathTags->item( $i );
+ '@phan-var DOMElement $pathElement';
$pathType = $this->getAttributeValue( $pathElement, 'type' );
$path = $pathElement->textContent;
$idTags = $siteElement->getElementsByTagName( 'localid' );
for ( $i = 0; $i < $idTags->length; $i++ ) {
$idElement = $idTags->item( $i );
+ '@phan-var DOMElement $idElement';
$idType = $this->getAttributeValue( $idElement, 'type' );
$id = $idElement->textContent;
*/
public function getTrail() {
return WrappedString::join( "\n", [
+ // @phan-suppress-next-line PhanTypeMismatchArgument
MWDebug::getDebugHTML( $this->getSkin()->getContext() ),
$this->get( 'bottomscripts' ),
$this->get( 'reporttime' )
private $existingPropNames = null;
/**
- * @var string|null
+ * @var int|null
*/
private $ns;
$request = $this->getRequest();
$propname = $request->getVal( 'propname', $par );
+ $this->ns = $request->getIntOrNull( 'namespace' );
$this->reverse = $request->getBool( 'reverse' );
$this->sortByValue = $request->getBool( 'sortbyvalue' );
'type' => 'namespaceselect',
'name' => 'namespace',
'label-message' => 'namespace',
- 'all' => null,
- 'default' => null,
+ 'all' => '',
+ 'default' => $this->ns,
],
'reverse' => [
'type' => 'check',
public function onSubmit( $data, $form ) {
$this->propName = $data['propname'];
- $this->ns = $data['namespace'];
parent::execute( $data['propname'] );
}
'options' => []
];
- if ( $this->ns && isset( $this->ns ) ) {
+ if ( $this->ns !== null ) {
$query['conds']['page_namespace'] = $this->ns;
}
"tog-watchmoves": "Přidávat mnou přesouvané stránky a soubory mezi sledované",
"tog-watchdeletion": "Přidávat stránky a soubory, které smažu, mezi sledované",
"tog-watchuploads": "Přidávat mnou načtené soubory ke sledovaným",
- "tog-watchrollback": "Přidávat stránky, které jsem {{GENDER:|vrátil|vrátila}} zpět, ke sledovaným",
+ "tog-watchrollback": "Přidávat stránky, kde jsem {{GENDER:|použil|použila}} vrácení zpět, ke sledovaným",
"tog-minordefault": "Označovat editace implicitně jako malé",
"tog-previewontop": "Zobrazovat náhled před editačním oknem (ne za ním)",
"tog-previewonfirst": "Zobrazit při první editaci náhled",
"tog-norollbackdiff": "Po vrácení změny nezobrazovat porovnání rozdílů",
"tog-useeditwarning": "Upozornit, když budu opouštět editaci bez uložení změn",
"tog-prefershttps": "Po přihlášení vždy používat zabezpečené připojení",
- "tog-showrollbackconfirmation": "Při kliknutí na odkaz pro vrácení editace zobrazit žádost o potvrzení",
+ "tog-showrollbackconfirmation": "Při kliknutí na odkaz pro rychlý revert zobrazit žádost o potvrzení",
"tog-requireemail": "Pro obnovu hesla vyžadovat e-mail",
"underline-always": "Vždy",
"underline-never": "Nikdy",
"category_header": "Stránky v kategorii „$1“",
"subcategories": "Podkategorie",
"category-media-header": "Soubory v kategorii „$1“",
- "category-empty": "''Tato kategorie neobsahuje žádné stránky či soubory.''",
+ "category-empty": "<em>Tato kategorie neobsahuje žádné stránky či soubory.</em>",
"hidden-categories": "{{PLURAL:$1|Skrytá kategorie|Skryté kategorie|Skryté kategorie}}",
"hidden-category-category": "Skryté kategorie",
"category-subcat-count": "{{PLURAL:$2|V této kategorii je pouze následující podkategorie.|{{PLURAL:$1|Zobrazuje se jedna podkategorie|Zobrazují se $1 podkategorie|Zobrazuje se $1 podkategorií}} z celkového počtu $2 podkategorií v této kategorii.|{{PLURAL:$1|Zobrazuje se jedna podkategorie|Zobrazují se $1 podkategorie|Zobrazuje se $1 podkategorií}} z celkového počtu $2 podkategorií v této kategorii.}}",
"listfiles-userdoesnotexist": "Das Benutzerkonto „$1“ ist nicht registriert.",
"imgfile": "Datei",
"listfiles": "Dateiliste",
+ "listfiles_subpage": "Von $1 hochgeladene Dateien",
"listfiles_thumb": "Vorschaubild",
"listfiles_date": "Datum",
"listfiles_name": "Name",
"mycustomjsredirectprotected": "Du hast keine Berechtigung, diese JavaScript-Seite zu bearbeiten, da sie eine Weiterleitung, die nicht in deinen Benutzernamensraum zeigt, enthält.",
"easydeflate-invaliddeflate": "Der angegebene Inhalt ist nicht ordnungsgemäß komprimiert",
"unprotected-js": "Aus Sicherheitsgründen kann JavaScript-Code nicht mehr von ungeschützten Seiten geladen werden. Erstelle die JavaScript-Seite bitte ausschließlich im Namensraum „MediaWiki“ oder als Benutzerunterseite.",
- "userlogout-continue": "Möchtest du dich abmelden?"
+ "userlogout-continue": "Möchtest du dich abmelden?",
+ "rest-prefix-mismatch": "Der angeforderte Pfad ($1) kannte nicht innerhalb des REST-API-Root-Pfades ($2) gefunden werden"
}
"upload_directory_read_only": "Direktorê dosyayê ($1)î webserver de nieşkeno binuse.",
"uploaderror": "Ğeletê bar kerdişî",
"upload-recreate-warning": "'''Diqet: Yew dosya pê ena name wedariya ya zi vurniya.'''\n\nLogê wedariyayiş u berdişi seba ena pele a ti ra xezir kerda:",
- "uploadtext": "Qey barkerdişê dosyayî, formê cêrinî bişuxulne.\nDosyayê ke vera cû bar biyê eke şima qayîl e ney dosyayan bivînê ya zî bigerî biewnê[[Special:FileList|listeyê dosyayê bar bîyaye]] (tekrar) bar bîyaye [[Special:Log/upload|rocaneyê barkerdişî]] de, hewn a şîyaye zî tîya de [[Special:Log/delete|rocaneyê hewn a kerdişî]] pawiyene.\n\nwexta şima qayîl e yew peli re dosya bierzî, formanê cêrinan ra yewi bişuxulne;\n* Qey xebitnayişê dosyayî: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Dosya.jpg]]</nowiki></code>'''\n*Heto çep de zerreyê yew qutî de, qey xebitnayişi 'nuşteyê binîn' û 200 pikseli: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Dosya.png|200px|thumb|left|alt metin]]</nowiki></code>'''\n* Dosya memocın, dosya te direk gırey bıerz: '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Dosya.ogg]]</nowiki></code>'''",
+ "uploadtext": "Seba '''dosya''' barkerdışi rê formê cerênê bıkarnê. Veri ra bar bıyaye dosyaya vınayış u cıgeyrayışi rê bıewni rê [[Special:FileList|lista dosyayan]], seba (fına ) barbıyayan rê [[Special:Log/upload|roceka barkerdışi ]] u, esterıtan zi pela [[Special:Log/delete|roceka esterıtışi]] de tepışiyeno.\n\nYew pela rê Dosya cıkerdışi rê formanê cêrênan ra yewi bıkarnê;\n* Versiyonê pêroyiya Dosya karnayışi rê: '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Dosya.jpg]]</nowiki></code>'''\n* Kışta çepa yew dorek miyan de, vıniyao cı de 'metinê bıni' ya, 200 piksel ebatiya Dosya karnayışi rê : '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Dosya.png|200px|thumb|left|alt metin]]</nowiki></code>'''\n* Dosyay nêmusnayışi ra, Dosya rê direkt Link dayışi rê : '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Dosya.ogg]]</nowiki></code>'''",
"upload-permitted": "{{PLURAL:$2|Babetê|Babetên}} dosyayanê vêrdeyan: $1.",
"upload-preferred": "{{PLURAL:$2|Babetê|Babetên}} dosyayanê tercihbiyayeyan: $1.",
"upload-prohibited": "{{PLURAL:$2|Babetê|Babetên}} dosyayanê tometebiyayeyan: $1.",
"exif-gpsspeed": "Хәрәкәт тизлеге",
"exif-gpsdatestamp": "GPS датасы",
"exif-keywords": "Иң мөһиме",
+ "exif-countrydest": "Күрсәтелгән ил",
+ "exif-countrycodedest": "Күрсәтелгән илнең коды",
+ "exif-provinceorstatedest": "Күрсәтелгән өлкә яки штат",
+ "exif-citydest": "Күрсәтелгән шәһәр",
+ "exif-sublocationdest": "Күрсәтелгән шәһәрнең җире",
+ "exif-objectname": "Кыска исем",
"exif-headline": "Башисем",
"exif-source": "Чыганак",
"exif-contact": "Элемтә өчен мәгълүмат",
"exif-iimversion": "IIM юрамасы",
"exif-iimcategory": "Төркем",
"exif-iimsupplementalcategory": "Өстәмә төркемнәр",
- "exif-datetimereleased": "ЧÑ\8bгаÑ\80Ñ\8bлÑ\83 вакыты",
+ "exif-datetimereleased": "ЧÑ\8bгаÑ\80Ñ\8bлÑ\8bÑ\88 вакыты",
"exif-identifier": "Идентификатор",
"exif-cameraownername": "Камера иясе",
"exif-label": "Билгеләү",
"createaccountmail": "Átmeneti, véletlenszerű jelszó beállítása és kiküldése a megadott e-mail-címre",
"createaccountmail-help": "A jelszó megismerése nélkül készíthető valaki másnak fiók.",
"createacct-realname": "Igazi neved (nem kötelező)",
- "createacct-reason": "Indoklás",
+ "createacct-reason": "Indoklás (nyilvánosan naplózva)",
"createacct-reason-ph": "Miért hozol létre egy másik fiókot",
"createacct-reason-help": "A fióklétrehozási naplóban megjelenő üzenet",
"createacct-submit": "Felhasználói fiók létrehozása",
"uploadstash-zero-length": "A fájl nulla méretű.",
"invalid-chunk-offset": "Érvénytelen darab eltolás",
"img-auth-accessdenied": "Hozzáférés megtagadva",
- "img-auth-nopathinfo": "Hiányzó PATH_INFO.\nA szerver nincs beállítva, hogy továbbítsa ezt az információt.\nLehet, hogy CGI-alapú, és nem támogatja az img_auth-ot.\nLásd https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization!",
+ "img-auth-nopathinfo": "Hiányzó elérési út információ.\nA szerveredet úgy kell beállítanod, hogy továbbítsa a REQUEST_URI és/vagy a PATH_INFO változókat.\nHa már be vannak, próbáld engedélyezni a $wgUsePathInfo-t.\nLásd https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization!",
"img-auth-notindir": "A kért elérési út nincs a beállított feltöltési könyvtárban.",
"img-auth-badtitle": "Nem sikerült érvényes címet készíteni a(z) „$1” szövegből.",
"img-auth-nofile": "A fájl („$1”) nem létezik.",
"listfiles-userdoesnotexist": "A(z) „$1” felhasználó nincs regisztrálva.",
"imgfile": "fájl",
"listfiles": "Fájllista",
+ "listfiles_subpage": "$1 feltöltései",
"listfiles_thumb": "Bélyegkép",
"listfiles_date": "Dátum",
"listfiles_name": "Név",
"listfiles-userdoesnotexist": "L'utenza \"$1\" non è registrata.",
"imgfile": "file",
"listfiles": "Elenco dei file",
+ "listfiles_subpage": "Caricamenti di $1",
"listfiles_thumb": "Miniatura",
"listfiles_date": "Data",
"listfiles_name": "Nome",
"emailuser-title-target": "Siųsti el. pašto žinutę {{GENDER:$1|naudotojui|naudotojai}}",
"emailuser-title-notarget": "El. pašto vartotojas",
"emailpagetext": "Jūs galite pasinaudoti šiuo pavyzdžiu, norėdami nusiųsti elektroninį laišką {{GENDER:$1|šiam naudotojui|šiai naudotojai}}.\nElektroninio pašto adresas, kurį įvedėte [[Special:Preferences|savo naudotojo nustatymuose]], bus rodomas kaip el. pašto siuntėjo adresas tam, kad gavėjas galėtų tiesiogiai jums atsakyti.",
- "defemailsubject": "{{SITENAME}} el. pašto iš vartotojo \" $1 \"",
+ "defemailsubject": "{{SITENAME}} laiškas iš naudotojo „$1“",
"usermaildisabled": "Naudotojo elektroninis paštas išjungtas",
"usermaildisabledtext": "Jūs negalite siūlsti el. laiško kitiems šio wiki projekto naudotojams.",
"noemailtitle": "Nėra el. pašto adreso",
"listfiles-userdoesnotexist": "A conta de usuário \"$1\" não está registrada.",
"imgfile": "arquivo",
"listfiles": "Lista de arquivos",
+ "listfiles_subpage": "Enviado por $1",
"listfiles_thumb": "Miniatura",
"listfiles_date": "Data",
"listfiles_name": "Nome",
"mycustomjsredirectprotected": "Você não tem permissão para editar esta página JavaScript porque é um redirecionamento e não aponta dentro do seu espaço do usuário.",
"easydeflate-invaliddeflate": "O conteúdo fornecido não está devidamente comprimido",
"unprotected-js": "Por razões de segurança o JavaScript não pode ser carregado de páginas desprotegidas. Por favor, crie apenas javascript no MediaWiki: namespace ou como uma subpágina do usuário",
- "userlogout-continue": "Você quer sair?"
+ "userlogout-continue": "Você quer sair?",
+ "rest-prefix-mismatch": "O caminho pedido ($1) não estava no interior do caminho raiz da API REST ($2)",
+ "rest-wrong-method": "O método pedido ($1) não era {{PLURAL:$3|o método permitido para este caminho|um dos métodos permitidos para este caminho}} ($2)",
+ "rest-no-match": "O caminho relativo pedido ($1) não corresponde a nenhuma rotina de tratamento conhecida"
}
"tog-useeditwarning": "Avvisave quanne jie lasse 'na pàgene cangiate senze ca agghie sarvate le cangiaminde",
"tog-prefershttps": "Ause sembre 'na connessione secure quanne trase",
"tog-showrollbackconfirmation": "Fà 'ndrucà 'na richieste de conferme quanne ste cazze sus a 'nu collegamende de annullamende",
+ "tog-requireemail": "Richeiste email pe l'azzeramende d'a passuord",
"underline-always": "Sembre",
"underline-never": "Maje",
"underline-default": "Valore de default d'u browser o scheme",
"content-model-css": "CSS",
"content-json-empty-object": "Oggette vacande",
"content-json-empty-array": "Matrice vacande",
+ "unsupported-content-diff": "Le differenze non ge sò supportate pu modelle de condenute $1.",
"deprecated-self-close-category": "Lè pàggene ca ausane le tag HTML auto-achiuse invalide",
"duplicate-args-warning": "<strong>Attenziò:</strong> [[:$1]] ste chiame [[:$2]] cu cchiù de 'nu valore pu parametre \"$3\". Sulamende l'urteme valore date avène ausate.",
"duplicate-args-category": "Pàggene ca ausane le argumende a doppie jndr'à le chiamate d'u template",
"listfiles-userdoesnotexist": "Nome utende \"$1\" non g'è reggistrate.",
"imgfile": "file",
"listfiles": "Liste de le fail",
+ "listfiles_subpage": "Carecaminde da $1",
"listfiles_thumb": "Miniature",
"listfiles_date": "Sciurne",
"listfiles_name": "Nome",
"createaccountmail": "Использовать сгенерированный случайным образом временный пароль и выслать его на указанный адрес электронной почты",
"createaccountmail-help": "Может использоваться, чтобы создать учётную запись для другого лица, не узнавая пароль.",
"createacct-realname": "Настоящее имя (необязательно)",
- "createacct-reason": "Причина",
+ "createacct-reason": "Причина (публично видимая)",
"createacct-reason-ph": "Зачем вы создаёте другую учётную запись",
"createacct-reason-help": "Сообщение, отображаемое в журнале создания учётных записей",
"createacct-submit": "Создать учётную запись",
"createaccountmail": "Використати тимчасовий випадковий пароль і надіслати його на вказану адресу електронної пошти",
"createaccountmail-help": "Може використовуватися, щоб створити обліковий запис для іншої особи, не дізнаючись пароль.",
"createacct-realname": "Справжнє ім'я (не обов'язково)",
- "createacct-reason": "Причина",
+ "createacct-reason": "Причина (публічно видима)",
"createacct-reason-ph": "Чому ви створюєте інший обліковий запис",
"createacct-reason-help": "Повідомлення, що показується в журналі створення облікових записів",
"createacct-submit": "Створіть ваш обліковий запис",
"ipblocklist-legend": "查找被封禁用户",
"blocklist-userblocks": "隐藏账户封禁",
"blocklist-tempblocks": "隐藏临时封禁",
+ "blocklist-indefblocks": "隐藏无限期封禁",
"blocklist-addressblocks": "隐藏单个IP封禁",
"blocklist-type": "类型:",
"blocklist-type-opt-all": "全部",
"tog-useeditwarning": "在我離開未儲存的編輯頁面時警告我",
"tog-prefershttps": "登入時永遠使用安全連線",
"tog-showrollbackconfirmation": "當點擊回退連結時顯示確認提示",
+ "tog-requireemail": "需要電子郵件用來重設密碼",
"underline-always": "永遠使用",
"underline-never": "永不使用",
"underline-default": "佈景主題或瀏覽器預設",
"createaccountmail": "使用臨時的隨機密碼,並將它寄至指定的電子郵件地址",
"createaccountmail-help": "可用來建立其他人的帳號 (不需要知道密碼)。",
"createacct-realname": "真實姓名 (選填)",
- "createacct-reason": "原因",
+ "createacct-reason": "原因(公開記錄)",
"createacct-reason-ph": "您為什麼要建立另一個帳號",
"createacct-reason-help": "顯示於帳號建立日誌的訊息",
"createacct-submit": "建立您的帳號",
"changeemail-oldemail": "目前的電子郵件地址:",
"changeemail-newemail": "新的電子郵件地址:",
"changeemail-newemail-help": "若您想移除您的電子郵件地址,此欄位應留空。若移除電子郵件地址您將無法重設忘記的密碼並且將不會再收到來自此 wiki 的電子郵件。",
- "changeemail-none": "(無)",
+ "changeemail-none": "(無)",
"changeemail-password": "您於 {{SITENAME}} 的密碼:",
"changeemail-submit": "變更電子郵件",
"changeemail-throttled": "您最近嘗試了太多次登入。\n請等待 $1 後再試。",
"undo-main-slot-only": "編輯無法還原,因為有包含到在主分配之外的內容。",
"undo-norev": "此編輯不存在或已被刪除,無法還原。",
"undo-nochange": "此編輯已被還原。",
- "undo-summary": "取消由 [[Special:Contributions/$2|$2]] ([[User talk:$2|討論]]) 所作出的修訂 $1",
+ "undo-summary": "取消由[[Special:Contributions/$2|$2]]([[User talk:$2|討論]])所作出的修訂$1",
+ "undo-summary-anon": "取消由[[Special:Contributions/$2|$2]]所作出的修訂$1",
"undo-summary-username-hidden": "還原隱藏使用者的修訂 $1",
"cantcreateaccount-text": "自這個 IP 位址 (<strong>$1</strong>) 建立帳號已經被 [[User:$3|$3]] 封鎖。\n\n$3 封鎖的原因是$2",
"cantcreateaccount-range-text": "來自 IP 位址範圍 <strong>$1</strong>,包含您的 IP 位址 (<strong>$4</strong>) 所建立的帳號已經被 [[User:$3|$3]] 封鎖。\n\n$3 封鎖的原因是 <em>$2</em>",
"prefs-help-gender": "此偏好設定為選填欄位。\n系統會使用您選擇的方式稱呼您,對他人提及您時也會使用適當語法稱呼。\n此項資訊會被公開。",
"email": "Email",
"prefs-help-realname": "真實姓名為選填欄位。\n若提供,真實姓名可能會用來作為您的作品的署名。",
- "prefs-help-email": "電子郵件地址為選填欄位。\n但在重設密碼時會使用,而您很有可能會忘記密碼。",
+ "prefs-help-email": "電子郵件地址為選填欄位,但是當您忘記密碼而要重設時需要此資訊。",
"prefs-help-email-others": "您亦可以選擇讓其他使用者透過您的電子郵件、使用者頁面或討論頁面的連結與您聯絡。\n您的電子郵件地址不會洩漏給其他要聯絡您的使用者。",
"prefs-help-email-required": "電子郵件地址是必填項目。",
+ "prefs-help-requireemail": "如果選取,則只有在重設密碼的人同時提供此帳戶的使用者名稱和電子郵件時,才會發送重設密碼的電子郵件。",
"prefs-info": "基本資訊",
"prefs-i18n": "國際化",
"prefs-signature": "簽名",
"listfiles-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。",
"imgfile": "檔案",
"listfiles": "檔案清單",
+ "listfiles_subpage": "由 $1 上傳",
"listfiles_thumb": "縮圖",
"listfiles_date": "日期",
"listfiles_name": "名稱",
"alreadyrolled": "無法回退由[[User:$2|$2]]([[User talk:$2|討論]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]])所作的最後一次編輯[[:$1]],已有其他人編輯或回退了該頁面。\n\n最後一次編輯該頁面的使用者是[[User:$3|$3]]([[User talk:$3|討論]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])。",
"editcomment": "編輯摘要為:<em>$1</em>。",
"revertpage": "已還原[[Special:Contributions/$2|$2]]([[User talk:$2|討論]])的編輯至最後由[[User:$1|$1]]所修訂的版本",
+ "revertpage-anon": "已還原[[Special:Contributions/$2|$2]]的編輯至最後由[[User:$1|$1]]所修訂的版本",
"revertpage-nouser": "已還原隱藏使用者的編輯為最後 {{GENDER:$1|[[User:$1|$1]]}} 修訂的版本",
"rollback-success": "已還原{{GENDER:$3|$1}}所做的編輯;變更回由{{GENDER:$4|$2}}修訂的最後一個版本。",
"sessionfailure-title": "連線階段失敗",
"ipblocklist-legend": "搜尋已封鎖的使用者",
"blocklist-userblocks": "隱藏帳號封鎖",
"blocklist-tempblocks": "隱藏暫時封鎖",
+ "blocklist-indefblocks": "隱藏無限期封鎖",
"blocklist-addressblocks": "隱藏單一 IP 封鎖",
"blocklist-type": "類型:",
"blocklist-type-opt-all": "所有",
"mycustomjsredirectprotected": "您無權編輯此JavaScript頁面,因為它是重新導向,且不是重新導向到您的用戶空間。",
"easydeflate-invaliddeflate": "提供的內容未被正常的壓縮",
"unprotected-js": "基於安全因素,JavaScript 不能從未保護的頁面來載入。請僅在 MediaWiki:命名空間或使用者子頁面中建立 JavaScript。",
- "userlogout-continue": "您想要登出嗎?"
+ "userlogout-continue": "您想要登出嗎?",
+ "rest-prefix-mismatch": "請求的路徑($1)不在REST API的根路徑($2)內",
+ "rest-wrong-method": "請求的方法($1)不是{{PLURAL:$3|此路徑允許的方法|此路徑允許的方法之一}}($2)",
+ "rest-no-match": "請求的相對路徑($1)不符合任何已知的處理器"
}
);
if ( !$status->isGood() ) {
- $this->fatalError( $status->getWikiText( null, null, 'en' ) );
+ $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
}
$this->output( "$tag was created.\n" );
if ( $status->isGood() ) {
$this->output( "Password set for " . $user->getName() . "\n" );
} else {
- $this->fatalError( $status->getWikiText( null, null, 'en' ) );
+ $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
}
}
}
$mp = MediaWikiServices::getInstance()->getMovePageFactory()
->newMovePage( $current, $target );
$status = $mp->move( $this->user, $reason, $createRedirect );
- $ok = $status->isOK() ? 'OK' : $status->getWikiText( false, false, 'en' );
+ $ok = $status->isOK() ? 'OK' : $status->getMessage( false, false, 'en' )->text();
$this->output( "\"$display\" -> \"$targetDisplay\": $ok\n" );
}
// Note: prepare() is usually fast for key/value backends
$status = $dst->prepare( [ 'dir' => dirname( $dstPath ), 'bypassReadOnly' => 1 ] );
if ( !$status->isOK() ) {
- $this->error( print_r( Status::wrap( $status )->getWikiText(), true ) );
+ $this->error( Status::wrap( $status )->getMessage( false, false, 'en' )->text() );
$this->fatalError( "$domainId: Could not copy $srcPath to $dstPath." );
}
$ops[] = [ 'op' => 'store',
}
$elapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 );
if ( !$status->isOK() ) {
- $this->error( print_r( Status::wrap( $status )->getWikiText(), true ) );
+ $this->error( Status::wrap( $status )->getMessage( false, false, 'en' )->text() );
$this->fatalError( "$domainId: Could not copy file batch." );
} elseif ( count( $copiedRel ) ) {
$this->output( "\n\tCopied these file(s) [{$elapsed_ms}ms]:\n\t" .
}
$elapsed_ms = floor( ( microtime( true ) - $t_start ) * 1000 );
if ( !$status->isOK() ) {
- $this->error( print_r( Status::wrap( $status )->getWikiText(), true ) );
+ $this->error( Status::wrap( $status )->getMessage( false, false, 'en' )->text() );
$this->fatalError( "$domainId: Could not delete file batch." );
} elseif ( count( $deletedRel ) ) {
$this->output( "\n\tDeleted these file(s) [{$elapsed_ms}ms]:\n\t" .
false
);
if ( !$status->isGood() ) {
- $this->fatalError( $status->getWikiText( null, null, 'en' ) );
+ $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
}
}
'retype' => $password,
] );
if ( !$status->isGood() ) {
- throw new PasswordError( $status->getWikiText( null, null, 'en' ) );
+ throw new PasswordError( $status->getMessage( false, false, 'en' )->text() );
}
if ( $exists ) {
$this->output( "Password set.\n" );
$exit = 1;
}
if ( !$status->isGood() ) {
- $this->output( $status->getWikiText( false, false, 'en' ) . "\n" );
+ $this->output( $status->getMessage( false, false, 'en' )->text() . "\n" );
}
exit( $exit );
}
$statusRootPage = $importer->setTargetRootPage( $this->getOption( 'rootpage' ) );
if ( !$statusRootPage->isGood() ) {
// Die here so that it doesn't print "Done!"
- $this->fatalError( $statusRootPage->getMessage()->text() );
+ $this->fatalError( $statusRootPage->getMessage( false, false, 'en' )->text() );
return false;
}
}
$archive = $image->publish( $file, $flags, $publishOptions );
if ( !$archive->isGood() ) {
$this->output( "failed. (" .
- $archive->getWikiText( false, false, 'en' ) .
+ $archive->getMessage( false, false, 'en' )->text() .
")\n" );
$failed++;
continue;
try {
$installer = InstallerOverrides::getCliInstaller( $siteName, $adminName, $this->mOptions );
} catch ( \MediaWiki\Installer\InstallException $e ) {
- $this->output( $e->getStatus()->getMessage()->text() . "\n" );
+ $this->output( $e->getStatus()->getMessage( false, false, 'en' )->text() . "\n" );
return false;
}
->newMovePage( $source, $dest );
$status = $mp->move( $wgUser, $reason, !$noredirects );
if ( !$status->isOK() ) {
- $this->output( "\nFAILED: " . $status->getWikiText( false, false, 'en' ) );
+ $this->output( "\nFAILED: " . $status->getMessage( false, false, 'en' )->text() );
}
$this->commitTransaction( $dbw, __METHOD__ );
$this->output( "\n" );
$this->output( "Done. Updated headers for $count file(s).\n" );
}
+ /**
+ * @param LocalRepo $repo
+ * @param array $backendOperations
+ */
protected function updateFileHeaders( $repo, $backendOperations ) {
$status = $repo->getBackend()->doQuickOperations( $backendOperations );
this.drawCarousel();
this.setSizeRequirement();
this.toggleThumbnails( !!this.$gallery.attr( 'data-showthumbnails' ) );
- this.showCurrentImage();
+ this.showCurrentImage( true );
// Events
$( window ).on(
/**
* Displays the image set as {@link #$currentImage} in the carousel.
+ *
+ * @param {boolean} init Image being show during gallery init (i.e. first image)
*/
- mw.GallerySlideshow.prototype.showCurrentImage = function () {
+ mw.GallerySlideshow.prototype.showCurrentImage = function ( init ) {
var $thumbnail, $imgLink,
$imageLi = this.getCurrentImage(),
$caption = $imageLi.find( '.gallerytext' );
if ( this.$thumbnail.attr( 'src' ) === $thumbnail.attr( 'src' ) ) {
this.$img.attr( 'src', info.thumburl );
this.setImageSize();
- mw.hook( 'wikipage.content' ).fire( this.$imgContainer );
+ // Don't fire hook twice during init
+ if ( !init ) {
+ mw.hook( 'wikipage.content' ).fire( this.$imgContainer );
+ }
// Pre-fetch the next image
this.loadImage( this.getNextImage().find( 'img' ) );
}
}
- $this->assertEquals( '', $bad );
+ $this->assertSame( '', $bad );
}
}
/**
* Empty all tables so they can be repopulated for tests
*
- * @param Database $db|null Database to reset
- * @param array $tablesUsed Tables to reset
+ * @param IDatabase $db|null Database to reset
+ * @param string[] $tablesUsed Tables to reset
*/
- private function resetDB( $db, $tablesUsed ) {
+ private function resetDB( IDatabase $db = null, array $tablesUsed ) {
if ( $db ) {
- $userTables = [ 'user', 'user_groups', 'user_properties', 'actor' ];
- $pageTables = [
- 'page', 'revision', 'ip_changes', 'revision_comment_temp', 'comment', 'archive',
- 'revision_actor_temp', 'slots', 'content', 'content_models', 'slot_roles',
- 'change_tag',
- ];
- $loggingTables = [
- 'logging', 'log_search', 'change_tag',
+ // some groups of tables are connected such that if any is used, all should be cleared
+ $extraTables = [
+ 'user' => [ 'user', 'user_groups', 'user_properties', 'actor' ],
+ 'page' => [ 'page', 'revision', 'ip_changes', 'revision_comment_temp', 'comment', 'archive',
+ 'revision_actor_temp', 'slots', 'content', 'content_models', 'slot_roles',
+ 'change_tag' ],
+ 'logging' => [ 'logging', 'log_search', 'change_tag' ],
];
- $coreDBDataTables = array_merge( $userTables, $pageTables );
+ $coreDBDataTables = array_merge( $extraTables['user'], $extraTables['page'] );
- // some groups of tables are connected such that if any is used, all should be cleared
- $extraTables = [];
- if ( array_intersect( $tablesUsed, $userTables ) ) {
- $extraTables[] = $userTables;
+ foreach ( $extraTables as $i => $group ) {
+ if ( !array_intersect( $tablesUsed, $group ) ) {
+ unset( $extraTables[$i] );
+ }
+ }
+ $extraTables = array_values( $extraTables );
+ $tablesUsed = array_unique( array_merge( $tablesUsed, ...$extraTables ) );
+ if ( in_array( 'user', $tablesUsed ) ) {
TestUserRegistry::clear();
// Reset $wgUser, which is probably 127.0.0.1, as its loaded data is probably not valid
global $wgUser;
$wgUser->clearInstanceCache( $wgUser->mFrom );
}
- if ( array_intersect( $tablesUsed, $pageTables ) ) {
- $extraTables[] = $pageTables;
- }
- if ( array_intersect( $tablesUsed, $loggingTables ) ) {
- $extraTables[] = $loggingTables;
- }
- if ( $extraTables !== [] ) {
- $tablesUsed = array_unique( array_merge( $tablesUsed, ...$extraTables ) );
- }
// Postgres uses mwuser/pagecontent
// instead of user/text. But Postgres does not remap the
$this->mergeMwGlobalArrayValue( 'wgHooks', [ $hookName => [ $handler ] ] );
}
- /**
- * 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 {
- self::assertFileExists( $fileName );
- }
- self::assertEquals( file_get_contents( $fileName ), $actualData, $msg );
- }
-
/**
* Edits or creates a page/revision
* @param string $pageName Page title
$mock->expects( $this->never() )->method( $this->anythingBut( '__destruct' ) );
return $mock;
}
+
+ /**
+ * 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 {
+ self::assertFileExists( $fileName );
+ }
+ self::assertEquals( file_get_contents( $fileName ), $actualData, $msg );
+ }
}
wfGetDB( DB_MASTER )->commit( __METHOD__ );
- $this->assertEquals( 0, DeferredUpdates::pendingUpdatesCount(), 'No deferred updates' );
+ $this->assertSame( 0, DeferredUpdates::pendingUpdatesCount(), 'No deferred updates' );
if ( $expectedCode != EditPage::AS_BLANK_ARTICLE ) {
$latest = $page->getLatest();
public function testGetText() {
$req = new FauxRequest( [ 'x' => 'Value' ] );
$this->assertEquals( 'Value', $req->getText( 'x' ) );
- $this->assertEquals( '', $req->getText( 'z' ) );
+ $this->assertSame( '', $req->getText( 'z' ) );
}
/**
*/
public function testDummies() {
$req = new FauxRequest();
- $this->assertEquals( '', $req->getRawQueryString() );
- $this->assertEquals( '', $req->getRawPostString() );
- $this->assertEquals( '', $req->getRawInput() );
+ $this->assertSame( '', $req->getRawQueryString() );
+ $this->assertSame( '', $req->getRawPostString() );
+ $this->assertSame( '', $req->getRawInput() );
}
}
* @covers Html::expandAttributes
*/
public function testExpandAttributesForBooleans() {
- $this->assertEquals(
+ $this->assertSame(
'',
Html::expandAttributes( [ 'selected' => false ] ),
'Boolean attributes do not generates output when value is false'
);
- $this->assertEquals(
+ $this->assertSame(
'',
Html::expandAttributes( [ 'selected' => null ] ),
'Boolean attributes do not generates output when value is null'
$user = $context->getUser();
$user->setOption( 'showrollbackconfirmation', $rollbackEnabled );
- $this->assertEquals( 0, Title::newFromText( $title )->getArticleID() );
+ $this->assertSame( 0, Title::newFromText( $title )->getArticleID() );
$pageData = $this->insertPage( $title );
$page = WikiPage::factory( $pageData['title'] );
// This should do nothing. In particular, it should not create a service instance.
$services->resetServiceForTesting( 'Test' );
- $this->assertEquals( 0, $serviceCounter, 'No service instance should be created yet.' );
+ $this->assertSame( 0, $serviceCounter, 'No service instance should be created yet.' );
$oldInstance = $services->getService( 'Test' );
$this->assertEquals( 1, $serviceCounter, 'A service instance should exit now.' );
'Some syndication links should be there' );
} else {
$this->assertFalse( $outputPage->isSyndicated(), 'No syndication should be offered' );
- $this->assertEquals( 0, count( $outputPage->getSyndicationLinks() ),
+ $this->assertSame( 0, count( $outputPage->getSyndicationLinks() ),
'No syndication links should be there' );
}
}
namespace MediaWiki\Tests\Revision;
use CommentStoreComment;
+use ContentHandler;
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\MutableRevisionRecord;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Revision\SlotRecord;
+use MediaWiki\Storage\SqlBlobStore;
+use Revision;
+use StatusValue;
use TextContent;
use Title;
+use Wikimedia\TestingAccessWrapper;
use WikitextContent;
/**
]
] ], $result->getErrors() );
}
+
+ /**
+ * @covers \MediaWiki\Revision\RevisionStore::newRevisionsFromBatch
+ */
+ public function testNewRevisionFromBatchUsesGetBlobBatch() {
+ $page1 = $this->getTestPage();
+ $text = __METHOD__ . 'b-ä';
+ $editStatus = $this->editPage( $page1->getTitle()->getPrefixedDBkey(), $text . '1' );
+ $this->assertTrue( $editStatus->isGood(), 'Sanity: must create revision 1' );
+ /** @var Revision $rev1 */
+ $rev1 = $editStatus->getValue()['revision'];
+
+ $contentAddress = $rev1->getRevisionRecord()->getSlot( SlotRecord::MAIN )->getAddress();
+ $mockBlobStore = $this->getMockBuilder( SqlBlobStore::class )
+ ->disableOriginalConstructor()
+ ->getMock();
+ $mockBlobStore
+ ->expects( $this->once() )
+ ->method( 'getBlobBatch' )
+ ->with( [ $contentAddress ], $this->anything() )
+ ->willReturn( StatusValue::newGood( [
+ $contentAddress => 'Content_From_Mock'
+ ] ) );
+ $mockBlobStore
+ ->expects( $this->never() )
+ ->method( 'getBlob' );
+
+ $revStore = MediaWikiServices::getInstance()
+ ->getRevisionStoreFactory()
+ ->getRevisionStore();
+ $wrappedRevStore = TestingAccessWrapper::newFromObject( $revStore );
+ $wrappedRevStore->blobStore = $mockBlobStore;
+
+ $result = $revStore->newRevisionsFromBatch(
+ [ $this->revisionToRow( $rev1 ) ],
+ [
+ 'slots' => [ SlotRecord::MAIN ],
+ 'content' => true
+ ]
+ );
+ $this->assertTrue( $result->isGood() );
+ $this->assertSame( 'Content_From_Mock',
+ ContentHandler::getContentText( $result->getValue()[$rev1->getId()]
+ ->getContent( SlotRecord::MAIN ) ) );
+ }
}
use CommentStoreComment;
use Content;
+use ContentHandler;
use Exception;
use HashBagOStuff;
+use IDBAccessObject;
use InvalidArgumentException;
use Language;
use MediaWiki\Linker\LinkTarget;
* @return WikiPage
*/
protected function getTestPage( $pageTitle = null ) {
- if ( !is_null( $pageTitle ) && $this->testPage ) {
+ if ( is_null( $pageTitle ) && $this->testPage ) {
return $this->testPage;
}
) {
$page1 = $this->getTestPage();
$text = __METHOD__ . 'b-ä';
+ $editStatus = $this->editPage( $page1->getTitle()->getPrefixedDBkey(), $text . '1' );
+ $this->assertTrue( $editStatus->isGood(), 'Sanity: must create revision 1' );
/** @var Revision $rev1 */
- $rev1 = $page1->doEditContent(
- new WikitextContent( $text . '1' ),
- __METHOD__ . 'b',
- 0,
- false,
- $this->getTestUser()->getUser()
- )->value['revision'];
+ $rev1 = $editStatus->getValue()['revision'];
+
$page2 = $this->getTestPage( $otherPageTitle );
+ $editStatus = $this->editPage( $page2->getTitle()->getPrefixedDBkey(), $text . '2' );
+ $this->assertTrue( $editStatus->isGood(), 'Sanity: must create revision 2' );
/** @var Revision $rev2 */
- $rev2 = $page2->doEditContent(
- new WikitextContent( $text . '2' ),
- __METHOD__ . 'b',
- 0,
- false,
- $this->getTestUser()->getUser()
- )->value['revision'];
+ $rev2 = $editStatus->getValue()['revision'];
+
$store = MediaWikiServices::getInstance()->getRevisionStore();
$result = $store->newRevisionsFromBatch(
[ $this->revisionToRow( $rev1 ), $this->revisionToRow( $rev2 ) ],
);
$this->assertTrue( $result->isGood() );
$this->assertEmpty( $result->getErrors() );
+ /** @var RevisionRecord[] $records */
$records = $result->getValue();
$this->assertRevisionRecordMatchesRevision( $rev1, $records[$rev1->getId()] );
$this->assertRevisionRecordMatchesRevision( $rev2, $records[$rev2->getId()] );
$this->assertSame( $text . '1',
- $records[$rev1->getId()]->getContent( SlotRecord::MAIN )->serialize() );
+ ContentHandler::getContentText( $records[$rev1->getId()]->getContent( SlotRecord::MAIN ) ) );
$this->assertSame( $text . '2',
- $records[$rev2->getId()]->getContent( SlotRecord::MAIN )->serialize() );
+ ContentHandler::getContentText( $records[$rev2->getId()]->getContent( SlotRecord::MAIN ) ) );
$this->assertEquals( $page1->getTitle()->getDBkey(),
$records[$rev1->getId()]->getPageAsLinkTarget()->getDBkey() );
$this->assertEquals( $page2->getTitle()->getDBkey(),
$this->assertEmpty( $result->getValue() );
$this->assertEmpty( $result->getErrors() );
}
+
+ /**
+ * @covers \MediaWiki\Revision\RevisionStore::newRevisionsFromBatch
+ */
+ public function testNewRevisionsFromBatch_wrongTitle() {
+ $page1 = $this->getTestPage();
+ $text = __METHOD__ . 'b-ä';
+ $editStatus = $this->editPage( $page1->getTitle()->getPrefixedDBkey(), $text . '1' );
+ $this->assertTrue( $editStatus->isGood(), 'Sanity: must create revision 1' );
+ /** @var Revision $rev1 */
+ $rev1 = $editStatus->getValue()['revision'];
+
+ $this->setExpectedException( InvalidArgumentException::class );
+ MediaWikiServices::getInstance()->getRevisionStore()
+ ->newRevisionsFromBatch(
+ [ $this->revisionToRow( $rev1 ) ],
+ [],
+ IDBAccessObject::READ_NORMAL,
+ $this->getTestPage( 'Title_Other_Then_The_One_Revision_Belongs_To' )->getTitle()
+ );
+ }
+
+ /**
+ * @covers \MediaWiki\Revision\RevisionStore::newRevisionsFromBatch
+ */
+ public function testNewRevisionsFromBatch_DuplicateRows() {
+ $page1 = $this->getTestPage();
+ $text = __METHOD__ . 'b-ä';
+ $editStatus = $this->editPage( $page1->getTitle()->getPrefixedDBkey(), $text . '1' );
+ $this->assertTrue( $editStatus->isGood(), 'Sanity: must create revision 1' );
+ /** @var Revision $rev1 */
+ $rev1 = $editStatus->getValue()['revision'];
+
+ $this->setExpectedException( InvalidArgumentException::class );
+ MediaWikiServices::getInstance()->getRevisionStore()
+ ->newRevisionsFromBatch( [ $this->revisionToRow( $rev1 ), $this->revisionToRow( $rev1 ) ] );
+ }
}
);
$jobq->get( 'null' )->delete(); // clear jobqueue
- $this->assertEquals( 0, $jobq->get( 'null' )->getSize(),
+ $this->assertSame( 0, $jobq->get( 'null' )->getSize(),
'Job queue for NullJob has been cleaned' );
$cache->delete( $cache->makeKey( 'SiteStats', 'jobscount' ) );
'jobs count is kept in process cache' );
$cache->clearProcessCache();
- $this->assertEquals( 0, SiteStats::jobs() );
+ $this->assertSame( 0, SiteStats::jobs() );
}
}
$this->db->endAtomic( __METHOD__ ); // run deferred updates
- $this->assertEquals( 0, DeferredUpdates::pendingUpdatesCount(), 'No pending updates' );
+ $this->assertSame( 0, DeferredUpdates::pendingUpdatesCount(), 'No pending updates' );
}
/**
$this->db->endAtomic( __METHOD__ ); // run deferred updates
- $this->assertEquals( 0, DeferredUpdates::pendingUpdatesCount(), 'No pending updates' );
+ $this->assertSame( 0, DeferredUpdates::pendingUpdatesCount(), 'No pending updates' );
$this->assertNotFalse( $pcache->get( $page, $updater->getCanonicalParserOptions() ) );
}
$title2 = Title::newFromText( 'Foo' );
$this->assertNotSame( $title1, $title2, 'title cache should be empty' );
- $this->assertEquals( 0, $linkCache->getGoodLinkID( 'Foo' ), 'link cache should be empty' );
+ $this->assertSame( 0, $linkCache->getGoodLinkID( 'Foo' ), 'link cache should be empty' );
}
public function provideGetLinkURL() {
$this->assertNull( Xml::expandAttributes( null ),
'Converting a null list of attributes'
);
- $this->assertEquals( '', Xml::expandAttributes( [] ),
+ $this->assertSame( '', Xml::expandAttributes( [] ),
'Converting an empty list of attributes'
);
}
'titles' => 'User:' . implode( '|User:', $userNames ),
] );
- $this->assertEquals( 0, $genderCache->misses,
+ $this->assertSame( 0, $genderCache->misses,
'ApiPageSet does not prefill the gender cache correctly' );
$this->assertEquals( $userNames, array_keys( $genderCache->cache ),
'ApiPageSet does not prefill all users into the gender cache' );
$pages = array_values( $result[0]['query']['pages'] );
$this->assertCount( 1, $pages );
- $this->assertEquals( 0, $pages[0]['ns'] );
+ $this->assertSame( 0, $pages[0]['ns'] );
$this->assertEquals( $this->getPrefixedText( $target ), $pages[0]['title'] );
$this->assertArraySubsetsEqual(
$pages[0]['revisions'],
// $result[0]['query']['pages'] uses page ids as keys
$item = array_values( $result[0]['query']['pages'] )[0];
- $this->assertEquals( 0, $item['ns'] );
+ $this->assertSame( 0, $item['ns'] );
$this->assertEquals( 'ApiQueryWatchlistRawIntegrationTestPage', $item['title'] );
}
unset( $data[0]['query']['watchlist'][$index] );
}
}
- $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) );
+ $this->assertSame( 0, count( $data[0]['query']['watchlist'] ) );
return $data;
}
}
if ( $created ) {
- $this->assertNotEquals( 0, \User::idFromName( $username ) );
+ $this->assertNotNull( \User::idFromName( $username ) );
} else {
- $this->assertEquals( 0, \User::idFromName( $username ) );
+ $this->assertNull( \User::idFromName( $username ) );
}
$first = false;
$this->assertEquals( $expect, $ret );
$this->assertNotEquals( 0, $user->getId() );
$this->assertSame( 'UTSysop', $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, '{username} already exists locally' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( wfMessage( 'readonlytext', 'Because' ) ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'denied by wfReadOnly(): {reason}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'test' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'blacklisted in session {sessionid}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'test2' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'blacklisted in session {sessionid}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'noname' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username . '@', $user->getId() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'name "{username}" is not creatable' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'authmanager-autocreate-noperm' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'IP lacks the ability to create or autocreate accounts' ],
], $logger->getBuffer() );
unset( $lock );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'usernameinprogress' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'Could not acquire account creation lock' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'fail-in-pre' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'Provider denied creation of {username}: {reason}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'fail-in-primary' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'Provider denied creation of {username}: {reason}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'fail-in-secondary' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, 'Provider denied creation of {username}: {reason}' ],
], $logger->getBuffer() );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->unhook( 'LocalUserCreated' );
$this->assertEquals( \Status::newFatal( 'authmanager-autocreate-exception' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::DEBUG, '{username} denied by prior creation attempt failures' ],
], $logger->getBuffer() );
$user->setName( $username );
$ret = $this->manager->autoCreateUser( $user, AuthManager::AUTOCREATE_SOURCE_SESSION, true );
$this->assertEquals( \Status::newFatal( 'because' ), $ret );
- $this->assertEquals( 0, $user->getId() );
+ $this->assertSame( 0, $user->getId() );
$this->assertNotEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::INFO, 'creating new user ({username}) - from: {from}' ],
[ LogLevel::ERROR, '{username} failed with message {msg}' ],
} catch ( \Exception $ex ) {
$this->assertSame( 'Excepted', $ex->getMessage() );
}
- $this->assertEquals( 0, $user->getId() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $user->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::INFO, 'creating new user ({username}) - from: {from}' ],
[ LogLevel::ERROR, '{username} failed with exception {exception}' ],
$this->assertEquals( \Status::newGood(), $ret );
$this->assertNotEquals( 0, $user->getId() );
$this->assertEquals( $username, $user->getName() );
- $this->assertEquals( 0, $session->getUser()->getId() );
+ $this->assertSame( 0, $session->getUser()->getId() );
$this->assertSame( [
[ LogLevel::INFO, 'creating new user ({username}) - from: {from}' ],
], $logger->getBuffer() );
[ 'ir_ipb_id' => $block->getId() ]
);
- $this->assertEquals( 0, $result->numRows() );
+ $this->assertSame( 0, $result->numRows() );
}
/**
$this->assertEquals( 'Meta>MetaWikiUser', $block->getBlocker()->getName(),
'Correct blocker name' );
$this->assertEquals( 'Meta>MetaWikiUser', $block->getByName(), 'Correct blocker name' );
- $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' );
+ $this->assertSame( 0, $block->getBy(), 'Correct blocker id' );
}
protected function addXffBlocks() {
$this->makePage( 'Go', 'de', 'Race!' );
$dbw->endAtomic( __METHOD__ );
- $this->assertEquals( 0,
+ $this->assertSame( 0,
DeferredUpdates::pendingUpdatesCount(),
'Post-commit deferred update triggers a run of all updates' );
// Populate one key
$this->makePage( 'Key1', 'de', 'Value1' );
- $this->assertEquals( 0,
+ $this->assertSame( 0,
DeferredUpdates::pendingUpdatesCount(),
'Post-commit deferred update triggers a run of all updates' );
$this->assertEquals( 'Value1', $messageCache->get( 'Key1' ), 'Key1 was successfully edited' );
// Populate the second key
$this->makePage( 'Key2', 'de', 'Value2' );
- $this->assertEquals( 0,
+ $this->assertSame( 0,
DeferredUpdates::pendingUpdatesCount(),
'Post-commit deferred update triggers a run of all updates' );
$this->assertEquals( 'Value2', $messageCache->get( 'Key2' ), 'Key2 was successfully edited' );
MessageCache::singleton()->getMsgFromNamespace( 'allpages', $wgContLanguageCode );
- $this->assertEquals( 0, $dbr->trxLevel() );
+ $this->assertSame( 0, $dbr->trxLevel() );
$dbr->setFlag( DBO_TRX, $dbr::REMEMBER_PRIOR ); // make queries trigger TRX
MessageCache::singleton()->getMsgFromNamespace( 'go', $wgContLanguageCode );
$dbr->restoreFlags();
- $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (content language)" );
+ $this->assertSame( 0, $dbr->trxLevel(), "No DB read queries (content language)" );
}
public function testNoDBAccessNonContentLanguage() {
MessageCache::singleton()->getMsgFromNamespace( 'allpages/nl', 'nl' );
- $this->assertEquals( 0, $dbr->trxLevel() );
+ $this->assertSame( 0, $dbr->trxLevel() );
$dbr->setFlag( DBO_TRX, $dbr::REMEMBER_PRIOR ); // make queries trigger TRX
MessageCache::singleton()->getMsgFromNamespace( 'go/nl', 'nl' );
$dbr->restoreFlags();
- $this->assertEquals( 0, $dbr->trxLevel(), "No DB read queries (non-content language)" );
+ $this->assertSame( 0, $dbr->trxLevel(), "No DB read queries (non-content language)" );
}
/**
$this->assertEquals( '(recentchanges-page-added-to-category: ' . self::$pageName . ')',
self::$lastNotifyArgs[3] );
$this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
- $this->assertEquals( 0, self::$lastNotifyArgs[5] );
- $this->assertEquals( 0, self::$lastNotifyArgs[6] );
+ $this->assertSame( 0, self::$lastNotifyArgs[5] );
+ $this->assertSame( 0, self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
$this->assertEquals( 1, self::$lastNotifyArgs[8] );
$this->assertEquals( null, self::$lastNotifyArgs[9] );
- $this->assertEquals( 0, self::$lastNotifyArgs[10] );
+ $this->assertSame( 0, self::$lastNotifyArgs[10] );
}
public function testChangeRemovedNoRev() {
$this->assertEquals( '(recentchanges-page-removed-from-category: ' . self::$pageName . ')',
self::$lastNotifyArgs[3] );
$this->assertEquals( self::$pageName, self::$lastNotifyArgs[4]->getPrefixedText() );
- $this->assertEquals( 0, self::$lastNotifyArgs[5] );
- $this->assertEquals( 0, self::$lastNotifyArgs[6] );
+ $this->assertSame( 0, self::$lastNotifyArgs[5] );
+ $this->assertSame( 0, self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
$this->assertEquals( 1, self::$lastNotifyArgs[8] );
$this->assertEquals( null, self::$lastNotifyArgs[9] );
- $this->assertEquals( 0, self::$lastNotifyArgs[10] );
+ $this->assertSame( 0, self::$lastNotifyArgs[10] );
}
public function testChangeAddedWithRev() {
$this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
$this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
- $this->assertEquals( 0, self::$lastNotifyArgs[8] );
+ $this->assertSame( 0, self::$lastNotifyArgs[8] );
$this->assertEquals( '127.0.0.1', self::$lastNotifyArgs[9] );
- $this->assertEquals( 0, self::$lastNotifyArgs[10] );
+ $this->assertSame( 0, self::$lastNotifyArgs[10] );
}
public function testChangeRemovedWithRev() {
$this->assertEquals( self::$pageRev->getParentId(), self::$lastNotifyArgs[5] );
$this->assertEquals( $revision->getId(), self::$lastNotifyArgs[6] );
$this->assertEquals( null, self::$lastNotifyArgs[7] );
- $this->assertEquals( 0, self::$lastNotifyArgs[8] );
+ $this->assertSame( 0, self::$lastNotifyArgs[8] );
$this->assertEquals( '127.0.0.1', self::$lastNotifyArgs[9] );
- $this->assertEquals( 0, self::$lastNotifyArgs[10] );
+ $this->assertSame( 0, self::$lastNotifyArgs[10] );
}
}
$recentChange2 = $this->getEditChange( '20131103092253' );
$html = $enhancedChangesList->recentChangesLine( $recentChange2, false );
- $this->assertEquals( '', $html );
+ $this->assertSame( '', $html );
}
public function testRecentChangesPrefix() {
$this->assertEquals( false, $cacheEntry->watched, 'watched' );
$this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
- $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+ $this->assertSame( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
$this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
$this->assertUserLinks( $user->getName(), $cacheEntry );
$this->assertEquals( false, $cacheEntry->watched, 'watched' );
$this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
- $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+ $this->assertSame( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
$this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
$this->assertDeleteLogLink( $cacheEntry );
$this->assertEquals( false, $cacheEntry->watched, 'watched' );
$this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
- $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
+ $this->assertSame( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
$this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
$this->assertRevDel( $cacheEntry );
$content = null;
$text = ContentHandler::getContentText( $content );
- $this->assertEquals( '', $text );
+ $this->assertSame( '', $text );
}
public static function dataGetContentText_TextContent() {
$content = $handler->makeEmptyContent();
$this->assertTrue( $content->isEmpty() );
- $this->assertEquals( '', $content->getData() );
+ $this->assertSame( '', $content->getData() );
}
public static function dataIsSupportedFormat() {
public function testGetWikitextForTransclusion() {
$content = $this->newContent( 'hello world.' );
- $this->assertEquals( '', $content->getWikitextForTransclusion() );
+ $this->assertFalse( $content->getWikitextForTransclusion() );
}
/**
$content = $this->handler->makeEmptyContent();
$this->assertTrue( $content->isEmpty() );
- $this->assertEquals( '', $content->getText() );
+ $this->assertSame( '', $content->getText() );
}
public static function dataIsSupportedFormat() {
$oInfo = $context->exportSession();
$this->assertEquals( '127.0.0.1', $oInfo['ip'], "Correct initial IP address." );
- $this->assertEquals( 0, $oInfo['userId'], "Correct initial user ID." );
+ $this->assertSame( 0, $oInfo['userId'], "Correct initial user ID." );
$this->assertFalse( MediaWiki\Session\SessionManager::getGlobalSession()->isPersistent(),
'Global session isn\'t persistent to start' );
};
$factory = $this->newLBFactoryMultiLBs();
- $this->assertEquals( 0, $countLBsFunc( $factory ) );
+ $this->assertSame( 0, $countLBsFunc( $factory ) );
$dbw = $factory->getMainLB()->getConnection( DB_MASTER );
$this->assertEquals( 1, $countLBsFunc( $factory ) );
// Test that LoadBalancer instances made during pre-commit callbacks in do not
$called = 0;
$factory = $this->newLBFactoryMultiLBs();
- $this->assertEquals( 0, $countLBsFunc( $factory ) );
+ $this->assertSame( 0, $countLBsFunc( $factory ) );
$dbw = $factory->getMainLB()->getConnection( DB_MASTER );
$this->assertEquals( 1, $countLBsFunc( $factory ) );
// Test that LoadBalancer instances made during pre-commit callbacks in do not
/** @var IMaintainableDatabase $db */
$db = $lb->getConnection( DB_MASTER, [], '' );
- $this->assertEquals(
+ $this->assertSame(
'',
$db->getDomainId(),
'Null domain ID handle used'
);
- $this->assertEquals(
- '',
+ $this->assertNull(
$db->getDBname(),
'Null domain ID handle used'
);
- $this->assertEquals(
+ $this->assertSame(
'',
$db->tablePrefix(),
'Main domain ID handle used; prefix is empty though'
/** @var IMaintainableDatabase $db */
$db = $lb->getConnection( DB_MASTER, [], '' );
- $this->assertEquals( '', $db->getDomainID(), "Null domain used" );
+ $this->assertSame( '', $db->getDomainID(), "Null domain used" );
$this->assertEquals(
$this->quoteTable( $db, 'page' ),
$lb->forEachOpenConnection( function () use ( &$n ) {
++$n;
} );
- $this->assertEquals( 0, $n, "Connections closed" );
+ $this->assertSame( 0, $n, "Connections closed" );
$conn2 = $lb->getConnectionRef( DB_MASTER );
$this->assertEquals(
$this->assertEquals( 1, $wrapped->pages );
$this->assertEquals( 3, $wrapped->users );
$this->assertEquals( 1, $wrapped->images );
- $this->assertEquals( 0, $wrapped->edits );
- $this->assertEquals( 0, $wrapped->articles );
+ $this->assertSame( 0, $wrapped->edits );
+ $this->assertSame( 0, $wrapped->articles );
}
/**
$fi = SiteStats::images();
$ai = SiteStats::articles();
- $this->assertEquals( 0, DeferredUpdates::pendingUpdatesCount() );
+ $this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
$dbw->begin( __METHOD__ ); // block opportunistic updates
$this->assertEquals( 1, DeferredUpdates::pendingUpdatesCount() );
DeferredUpdates::doUpdates();
- $this->assertEquals( 0, DeferredUpdates::pendingUpdatesCount() );
+ $this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
SiteStats::unload();
$this->assertEquals( $pi + 2, SiteStats::pages(), 'page count' );
$be->getReadIndexFromParams( [ 'latest' => 1 ] ),
'Reads with "latest" flag use backend 1'
);
- $this->assertEquals(
+ $this->assertSame(
0,
$be->getReadIndexFromParams( [ 'latest' => 0 ] ),
'Reads without "latest" flag use backend 0'
* @covers File::getHashPath
*/
public function testGetHashPath() {
- $this->assertEquals( '', $this->file_hl0->getHashPath() );
+ $this->assertSame( '', $this->file_hl0->getHashPath() );
$this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() );
$this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() );
}
$s = $r->execute();
$errorMsg = $s->getErrorsByType( 'error' )[0]['message'];
- $this->assertEquals( 0, $r->getStatus() );
+ $this->assertSame( 0, $r->getStatus() );
$this->assertEquals( 'http-invalid-url', $errorMsg );
}
$s = $r->execute();
$errorMsg = $s->getErrorsByType( 'error' )[0]['message'];
- $this->assertEquals( 0, $r->getStatus() );
+ $this->assertSame( 0, $r->getStatus() );
$this->assertEquals( 'http-request-error', $errorMsg );
}
$s = $r->execute();
$errorMsg = $s->getErrorsByType( 'error' )[0]['message'];
- $this->assertEquals( 0, $r->getStatus() );
+ $this->assertSame( 0, $r->getStatus() );
$this->assertEquals( 'http-timed-out', $errorMsg );
}
$this->hideDeprecated( 'Http::getProxy' );
$this->setMwGlobals( 'wgHTTPProxy', false );
- $this->assertEquals(
+ $this->assertSame(
'',
Http::getProxy(),
'default setting'
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
$this->assertNull( $queue->push( $this->newJob() ), "Push worked ($desc)" );
$this->assertNull( $queue->batchPush( [ $this->newJob() ] ), "Push worked ($desc)" );
$queue->flushCaches();
$this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
$jobs = iterator_to_array( $queue->getAllQueuedJobs() );
$this->assertEquals( 2, count( $jobs ), "Queue iterator size is correct ($desc)" );
$job2 = $queue->pop();
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
$queue->flushCaches();
if ( $recycles ) {
$queue->ack( $job2 );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
$this->assertNull( $queue->batchPush( [ $this->newJob(), $this->newJob() ] ),
"Push worked ($desc)" );
$queue->delete();
$queue->flushCaches();
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
}
/**
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
$this->assertNull(
$queue->batchPush(
$queue->flushCaches();
$this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
$this->assertNull(
$queue->batchPush(
$queue->flushCaches();
$this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
$job1 = $queue->pop();
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
if ( $recycles ) {
$this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
}
$queue->ack( $job1 );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
}
/**
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
$root1 = Job::newRootJobParams( "nulljobspam:testId" ); // task ID/timestamp
for ( $i = 0; $i < 5; ++$i ) {
$queue->flushCaches();
$this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
$dupcount = 0;
$jobs = [];
$this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
for ( $i = 0; $i < 10; ++$i ) {
$this->assertNull( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" );
$this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" );
$queue->flushCaches();
- $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
- $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
+ $this->assertSame( 0, $queue->getSize(), "Queue is empty ($desc)" );
+ $this->assertSame( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
}
/**
$this->assertEquals( 1, JobQueueGroup::singleton()->getQueueSizes()['clearUserWatchlist'] );
$this->assertEquals( 2, $watchedItemStore->countWatchedItems( $user ) );
$this->runJobs( 1 );
- $this->assertEquals( 0, JobQueueGroup::singleton()->getQueueSizes()['clearUserWatchlist'] );
+ $this->assertSame( 0, JobQueueGroup::singleton()->getQueueSizes()['clearUserWatchlist'] );
$this->assertEquals( 2, $watchedItemStore->countWatchedItems( $user ) );
$this->assertTrue( $watchedItemStore->isWatched( $user, new TitleValue( 0, 'C' ) ) );
* Compare against an array so we get the cache content difference.
*/
protected function assertCacheEmpty( $cache, $msg = 'Cache should be empty' ) {
- $this->assertEquals( 0, $cache->getEntriesCount(), $msg );
+ $this->assertSame( 0, $cache->getEntriesCount(), $msg );
}
/**
$this->assertEquals( 'a', $entry['name'] );
$this->assertEquals( 'mark', $entry['entryType'] );
$this->assertArrayHasKey( 'startTime', $entry );
- $this->assertEquals( 0, $entry['duration'] );
+ $this->assertSame( 0, $entry['duration'] );
usleep( 100 );
$timing->mark( 'a' );
$cache->set( 'bar', 1, 10 );
$cache->set( 'baz', 1, -10 );
- $this->assertEquals( 0, $cacheInternal->bag['foo'][$cache::KEY_EXP], 'Indefinite' );
+ $this->assertSame( 0, $cacheInternal->bag['foo'][$cache::KEY_EXP], 'Indefinite' );
// 2 seconds tolerance
$this->assertEquals( time() + 10, $cacheInternal->bag['bar'][$cache::KEY_EXP], 'Future', 2 );
$this->assertEquals( time() - 10, $cacheInternal->bag['baz'][$cache::KEY_EXP], 'Past', 2 );
$v = $cache->getWithSetCallback(
$key, 30, $func, [ 'lowTTL' => 0, 'lockTSE' => 5 ] + $extOpts );
$this->assertEquals( $value, $v, "Value returned" );
- $this->assertEquals( 0, $wasSet, "Value not regenerated" );
+ $this->assertSame( 0, $wasSet, "Value not regenerated" );
$mockWallClock += 1;
$asycList[0](); // run the refresh callback
$asycList = [];
$this->assertEquals( 2, $wasSet, "Value calculated at later time" );
- $this->assertEquals( 0, count( $asycList ), "No deferred refreshes added." );
+ $this->assertSame( 0, count( $asycList ), "No deferred refreshes added." );
$v = $cache->getWithSetCallback( $key, 300, $func, $opts );
$this->assertEquals( $value, $v, "New value stored" );
$keyedIds, 30, $genFunc, [ 'lowTTL' => 0, 'lockTSE' => 5 ] + $extOpts );
$this->assertEquals( $value, $v[$keyB], "Value returned" );
$this->assertEquals( 1, $wasSet, "Value regenerated" );
- $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
+ $this->assertSame( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
$v = $cache->getMultiWithSetCallback(
$keyedIds, 30, $genFunc, [ 'lowTTL' => 0, 'lockTSE' => 5 ] + $extOpts );
$this->assertEquals( $value, $v[$keyB], "Value returned" );
$this->assertEquals( 1, $wasSet, "Value not regenerated" );
- $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
+ $this->assertSame( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
$mockWallClock += 1;
$keyedIds, 30, $genFunc, [ 'lowTTL' => 0 ] + $extOpts );
$this->assertEquals( $value, $v[$keyB], "Value returned" );
$this->assertEquals( 1, $wasSet, "Value regenerated" );
- $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
+ $this->assertSame( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
$v = $cache->getMultiWithUnionSetCallback(
$keyedIds, 30, $genFunc, [ 'lowTTL' => 0 ] + $extOpts );
$this->assertEquals( $value, $v[$keyB], "Value returned" );
$this->assertEquals( 1, $wasSet, "Value not regenerated" );
- $this->assertEquals( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
+ $this->assertSame( 0, $cache->getWarmupKeyMisses(), "Keys warmed in warmup cache" );
$mockWallClock += 1;
$wasSet = 0;
$v = $cache->getWithSetCallback( $key, 30, $funcV2, $verOpts + $extOpts );
$this->assertEquals( $valueV2, $v, "Value not regenerated (secondary key)" );
- $this->assertEquals( 0, $wasSet, "Value not regenerated (secondary key)" );
+ $this->assertSame( 0, $wasSet, "Value not regenerated (secondary key)" );
// Clear out the older or unversioned key
$cache->delete( $key, 0 );
$this->database->startAtomic( __METHOD__ );
$wrapper->trxStatus = Database::STATUS_TRX_ERROR;
$this->database->rollback( __METHOD__ );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
$this->assertEquals( Database::STATUS_TRX_NONE, $wrapper->trxStatus() );
$this->assertLastSql( 'BEGIN; ROLLBACK' );
$this->database->endAtomic( __METHOD__ );
$this->assertEquals( Database::STATUS_TRX_NONE, $wrapper->trxStatus() );
$this->assertLastSql( 'BEGIN; DELETE FROM x WHERE field = \'1\'; COMMIT' );
- $this->assertEquals( 0, $this->database->trxLevel(), 'Use after rollback()' );
+ $this->assertSame( 0, $this->database->trxLevel(), 'Use after rollback()' );
$this->database->begin( __METHOD__ );
$this->database->startAtomic( __METHOD__, Database::ATOMIC_CANCELABLE );
$this->database->commit( __METHOD__ );
// phpcs:ignore Generic.Files.LineLength
$this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; UPDATE y SET a = \'1\' WHERE field = \'1\'; ROLLBACK TO SAVEPOINT wikimedia_rdbms_atomic1; DELETE FROM y WHERE field = \'1\'; COMMIT' );
- $this->assertEquals( 0, $this->database->trxLevel(), 'Use after rollback()' );
+ $this->assertSame( 0, $this->database->trxLevel(), 'Use after rollback()' );
// Next transaction
$this->database->startAtomic( __METHOD__ );
$this->database->endAtomic( __METHOD__ );
$this->assertEquals( Database::STATUS_TRX_NONE, $wrapper->trxStatus() );
$this->assertLastSql( 'BEGIN; DELETE FROM x WHERE field = \'3\'; COMMIT' );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
}
/**
$this->assertFalse( $this->database->isOpen() );
$this->assertLastSql( 'BEGIN; DELETE FROM x WHERE field = \'3\'; ROLLBACK; SELECT 2' );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
}
/**
$this->assertFalse( $this->database->isOpen() );
$this->assertLastSql( 'BEGIN; DELETE FROM x WHERE field = \'3\'; ROLLBACK; SELECT 2' );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
}
/**
$this->assertFalse( $this->database->isOpen() );
$this->assertLastSql( 'BEGIN; DELETE FROM x WHERE field = \'3\'; ROLLBACK' );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
}
/**
$this->assertFalse( $this->database->isOpen() );
$this->assertLastSql( 'BEGIN; SELECT 1; ROLLBACK' );
- $this->assertEquals( 0, $this->database->trxLevel() );
+ $this->assertSame( 0, $this->database->trxLevel() );
}
/**
$db->method( 'isOpen' )->willReturn( true );
$db->method( 'getDBname' )->willReturn( 'unittest' );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
$this->assertEquals( true, $db->lock( 'x', __METHOD__ ) );
$this->assertEquals( false, $db->lockIsFree( 'x', __METHOD__ ) );
$this->assertEquals( true, $db->unlock( 'x', __METHOD__ ) );
$this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$db->setFlag( DBO_TRX );
$this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) );
$db->clearFlag( DBO_TRX );
// Pending writes with DBO_TRX
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertTrue( $db->lockIsFree( 'meow', __METHOD__ ) );
$db->setFlag( DBO_TRX );
$db->query( "DELETE FROM test WHERE t = 1" ); // trigger DBO_TRX transaction before lock
$db->rollback( __METHOD__, IDatabase::FLUSHING_ALL_PEERS );
// Pending writes without DBO_TRX
$db->clearFlag( DBO_TRX );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertTrue( $db->lockIsFree( 'meow2', __METHOD__ ) );
$db->begin( __METHOD__ );
$db->query( "DELETE FROM test WHERE t = 1" ); // trigger DBO_TRX transaction before lock
$db->rollback( __METHOD__ );
// No pending writes, with DBO_TRX
$db->setFlag( DBO_TRX );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertTrue( $db->lockIsFree( 'wuff', __METHOD__ ) );
$db->query( "SELECT 1", __METHOD__ );
$this->assertEquals( 1, $db->trxLevel() );
$lock = $db->getScopedLockAndFlush( 'wuff', __METHOD__, 1 );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertFalse( $db->lockIsFree( 'wuff', __METHOD__ ), 'Lock already acquired' );
$db->rollback( __METHOD__, IDatabase::FLUSHING_ALL_PEERS );
// No pending writes, without DBO_TRX
$db->clearFlag( DBO_TRX );
- $this->assertEquals( 0, $db->trxLevel() );
+ $this->assertSame( 0, $db->trxLevel() );
$this->assertTrue( $db->lockIsFree( 'wuff2', __METHOD__ ) );
$db->begin( __METHOD__ );
try {
$linkRenderer = new LinkRenderer( $titleFormatter, $linkCache, $nsInfo );
$linkRenderer->setStubThreshold( 0 );
- $this->assertEquals(
+ $this->assertSame(
'',
$linkRenderer->getLinkClasses( $foobarTitle )
);
);
$linkRenderer->setStubThreshold( 20 );
- $this->assertEquals(
+ $this->assertSame(
'',
$linkRenderer->getLinkClasses( $userTitle )
);
'%[jpeg:sampling-factor]',
$path
)->execute();
- $this->assertEquals( 0,
+ $this->assertSame( 0,
$result->getExitCode(),
"ImageMagick's identify command should return success"
);
$meta = PNGMetadataExtractor::getMetadata( $this->filePath .
'Png-native-test.png' );
- $this->assertEquals( 0, $meta['frameCount'] );
+ $this->assertSame( 0, $meta['frameCount'] );
$this->assertEquals( 1, $meta['loopCount'] );
- $this->assertEquals( 0, $meta['duration'] );
+ $this->assertSame( 0.0, $meta['duration'] );
}
/**
$this->assertEquals( 20, $meta['frameCount'] );
// Note loop count of 0 = infinity
- $this->assertEquals( 0, $meta['loopCount'] );
+ $this->assertSame( 0, $meta['loopCount'] );
$this->assertEquals( 1.5, $meta['duration'], '', 0.00001 );
}
$n = $res->numRows();
$res->free();
- $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
+ $this->assertSame( 0, $n, 'pagelinks should contain no more links from the page' );
}
/**
$n = $res->numRows();
$res->free();
- $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
+ $this->assertSame( 0, $n, 'pagelinks should contain no more links from the page' );
}
/**
$page->updateCategoryCounts( [ 'A' ], [], 0 );
$this->assertEquals( 1, Category::newFromName( 'A' )->getPageCount() );
- $this->assertEquals( 0, Category::newFromName( 'B' )->getPageCount() );
- $this->assertEquals( 0, Category::newFromName( 'C' )->getPageCount() );
+ $this->assertSame( 0, Category::newFromName( 'B' )->getPageCount() );
+ $this->assertSame( 0, Category::newFromName( 'C' )->getPageCount() );
// Add a new category
$page->updateCategoryCounts( [ 'B' ], [], 0 );
$this->assertEquals( 1, Category::newFromName( 'A' )->getPageCount() );
$this->assertEquals( 1, Category::newFromName( 'B' )->getPageCount() );
- $this->assertEquals( 0, Category::newFromName( 'C' )->getPageCount() );
+ $this->assertSame( 0, Category::newFromName( 'C' )->getPageCount() );
// Add and remove a category
$page->updateCategoryCounts( [ 'C' ], [ 'A' ], 0 );
- $this->assertEquals( 0, Category::newFromName( 'A' )->getPageCount() );
+ $this->assertSame( 0, Category::newFromName( 'A' )->getPageCount() );
$this->assertEquals( 1, Category::newFromName( 'B' )->getPageCount() );
$this->assertEquals( 1, Category::newFromName( 'C' )->getPageCount() );
}
] );
$context = $this->getResourceLoaderContext( [], $rl );
- $this->assertEquals(
+ $this->assertSame(
'',
$rl->getCombinedVersion( $context, [] ),
'empty list'
*/
public function testNumRows() {
$resultSet = new SearchNearMatchResultSet( null );
- $this->assertEquals( 0, $resultSet->numRows() );
+ $this->assertSame( 0, $resultSet->numRows() );
$resultSet = new SearchNearMatchResultSet( Title::newMainPage() );
$this->assertEquals( 1, $resultSet->numRows() );
$wrapper = TestingAccessWrapper::newFromObject( $command );
$this->assertEquals( $expected, $wrapper->command );
- $this->assertEquals( 0, $wrapper->restrictions & Shell::NO_LOCALSETTINGS );
+ $this->assertSame( 0, $wrapper->restrictions & Shell::NO_LOCALSETTINGS );
}
public function provideMakeScriptCommand() {
$this->assertNull( $site );
$sites = $store->getSites();
- $this->assertEquals( 0, $sites->count() );
+ $this->assertSame( 0, $sites->count() );
}
/**
$this->assertNull( $site );
$sites = $store->getSites();
- $this->assertEquals( 0, $sites->count() );
+ $this->assertSame( 0, $sites->count() );
}
/**
$path = '//acme.com/'; // protocol-relative URL
$site->setPath( $type, $path );
- $this->assertEquals( '', $site->getProtocol() );
+ $this->assertSame( '', $site->getProtocol() );
}
public static function provideGetPageUrl() {
$this->markTestSkippedIfDbType( 'postgres' );
$users = User::findUsersByGroup( [] );
- $this->assertEquals( 0, iterator_count( $users ) );
+ $this->assertSame( 0, iterator_count( $users ) );
$users = User::findUsersByGroup( 'foo' );
- $this->assertEquals( 0, iterator_count( $users ) );
+ $this->assertSame( 0, iterator_count( $users ) );
$user = $this->getMutableTestUser( [ 'foo' ] )->getUser();
$users = User::findUsersByGroup( 'foo' );
$this->assertInstanceOf( WatchedItem::class, $watchedItem );
$this->assertEquals( 1, $watchedItem->getUser()->getId() );
$this->assertEquals( 'SomeDbKey', $watchedItem->getLinkTarget()->getDBkey() );
- $this->assertEquals( 0, $watchedItem->getLinkTarget()->getNamespace() );
+ $this->assertSame( 0, $watchedItem->getLinkTarget()->getNamespace() );
}
public function testLoadWatchedItem_noItem() {
$this->assertInstanceOf( WatchedItem::class, $watchedItem );
$this->assertEquals( 1, $watchedItem->getUser()->getId() );
$this->assertEquals( 'SomeDbKey', $watchedItem->getLinkTarget()->getDBkey() );
- $this->assertEquals( 0, $watchedItem->getLinkTarget()->getNamespace() );
+ $this->assertSame( 0, $watchedItem->getLinkTarget()->getNamespace() );
}
public function testGetWatchedItem_cachedItem() {
$index = $indexList->next();
$this->assertEquals( 'baz_index2', $index->name );
$this->assertEquals( '1', $index->unique );
- $this->assertEquals( 0,
+ $this->assertSame( 0,
$db->selectField( 'sqlite_master', 'COUNT(*)', [ 'name' => 'baz' ] ),
'Create a temporary duplicate only'
);
$databaseCreation = $db->query( 'CREATE TABLE a ( a_1 )', __METHOD__ );
$this->assertInstanceOf( ResultWrapper::class, $databaseCreation, "Failed to create table a" );
$res = $db->select( 'a', '*' );
- $this->assertEquals( 0, $db->numFields( $res ), "expects to get 0 fields for an empty table" );
+ $this->assertSame( 0, $db->numFields( $res ), "expects to get 0 fields for an empty table" );
$insertion = $db->insert( 'a', [ 'a_1' => 10 ], __METHOD__ );
$this->assertTrue( $insertion, "Insertion failed" );
$res = $db->select( 'a', '*' );
$s = $lang->getMessageFromDB( 'word-separator' );
$c = $lang->getMessageFromDB( 'comma-separator' );
- $this->assertEquals( '', $lang->listToText( [] ) );
+ $this->assertSame( '', $lang->listToText( [] ) );
$this->assertEquals( 'a', $lang->listToText( [ 'a' ] ) );
$this->assertEquals( "a{$and}{$s}b", $lang->listToText( [ 'a', 'b' ] ) );
$this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( [ 'a', 'b', 'c' ] ) );
// 2. Do the real output checking on our own.
$lines = explode( "\n", $this->getActualOutput() );
$this->assertGreaterThan( 1, count( $lines ), "Minimal lines of produced output" );
- $this->assertEquals( '', array_pop( $lines ), "Output ends in LF" );
+ $this->assertSame( '', array_pop( $lines ), "Output ends in LF" );
$timestamp_re = "[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-6][0-9]";
foreach ( $lines as $line ) {
$this->assertRegExp(
*/
public function testNorig() {
$obj = new FakeDiffOp();
- $this->assertEquals( 0, $obj->norig() );
+ $this->assertSame( 0, $obj->norig() );
$obj->orig = [ 'foo' ];
$this->assertEquals( 1, $obj->norig() );
}
*/
public function testNclosing() {
$obj = new FakeDiffOp();
- $this->assertEquals( 0, $obj->nclosing() );
+ $this->assertSame( 0, $obj->nclosing() );
$obj->closing = [ 'foo' ];
$this->assertEquals( 1, $obj->nclosing() );
}
public function testConstruct() {
$pf = new PasswordFactory();
$this->assertEquals( [ '' ], array_keys( $pf->getTypes() ) );
- $this->assertEquals( '', $pf->getDefaultType() );
+ $this->assertSame( '', $pf->getDefaultType() );
$pf = new PasswordFactory( [
'foo' => [ 'class' => 'FooPassword' ],
*/
public function testAppend() {
$set = SearchSuggestionSet::emptySuggestionSet();
- $this->assertEquals( 0, $set->getSize() );
+ $this->assertSame( 0, $set->getSize() );
$set->append( new SearchSuggestion( 3 ) );
$this->assertEquals( 3, $set->getWorstScore() );
$this->assertEquals( 3, $set->getBestScore() );
*/
public function testInsertBest() {
$set = SearchSuggestionSet::emptySuggestionSet();
- $this->assertEquals( 0, $set->getSize() );
+ $this->assertSame( 0, $set->getSize() );
$set->prepend( new SearchSuggestion( 3 ) );
$this->assertEquals( 3, $set->getWorstScore() );
$this->assertEquals( 3, $set->getBestScore() );
$this->assertEquals( 10, $set->getSize() );
$set->shrink( 0 );
- $this->assertEquals( 0, $set->getSize() );
+ $this->assertSame( 0, $set->getSize() );
}
// TODO: test for fromTitles
// Sauce Labs
// ======
// See http://webdriver.io/guide/services/sauce.html
- // and https://docs.saucelabs.com/reference/platforms-configurator
- services: [ 'sauce' ],
- user: process.env.SAUCE_USERNAME,
- key: process.env.SAUCE_ACCESS_KEY,
-
- // Default timeout in milliseconds for Selenium Grid requests
- connectionRetryTimeout: 90 * 1000,
-
- // Default request retries count
- connectionRetryCount: 3,
+ // and https://github.com/bermi/sauce-connect-launcher#advanced-usage
+ services: process.env.SAUCE_ACCESS_KEY ? [ 'sauce' ] : [],
// ==================
// Test Files