From b8efacc22706abb4af6fec4429931417a8a21e45 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 20 Sep 2019 14:35:39 -0400 Subject: [PATCH] CommentStore: Accept SCHEMA_COMPAT_* constants Extensions doing an actor and comment migration at the same time will likely want to use the same constants for each, and that will most likely be using write-both/read-old and write-both/read-new for the middle stages rather than write-both/read-both and write-new/read-both as implemented by the MIGRATION_* constants. See Ie29fd05 for example. This patch changes CommentStore's internal logic to work correctly when passed write-both/read-old or write-both/read-new. Bug: T233449 Change-Id: Iebec80f969ad1c4f9f51a4f25656319cca32b0dd --- includes/CommentStore.php | 69 ++++--- tests/phpunit/includes/CommentStoreTest.php | 201 +++++++++++++++++++- 2 files changed, 235 insertions(+), 35 deletions(-) diff --git a/includes/CommentStore.php b/includes/CommentStore.php index 994a064f2c..9054e7afe8 100644 --- a/includes/CommentStore.php +++ b/includes/CommentStore.php @@ -83,7 +83,8 @@ class CommentStore { protected $key = null; /** - * @var int One of the MIGRATION_* constants + * @var int One of the MIGRATION_* constants, or an appropriate combination + * of SCHEMA_COMPAT_* constants. * @todo Deprecate and remove once extensions seem unlikely to need to use * it for migration anymore. */ @@ -98,11 +99,19 @@ class CommentStore { /** * @param Language $lang Language to use for comment truncation. Defaults * to content language. - * @param int $migrationStage One of the MIGRATION_* constants. Always - * MIGRATION_NEW for MediaWiki core since 1.33. + * @param int $stage One of the MIGRATION_* constants, or an appropriate + * combination of SCHEMA_COMPAT_* constants. Always MIGRATION_NEW for + * MediaWiki core since 1.33. */ - public function __construct( Language $lang, $migrationStage ) { - $this->stage = $migrationStage; + public function __construct( Language $lang, $stage ) { + if ( ( $stage & SCHEMA_COMPAT_WRITE_BOTH ) === 0 ) { + throw new InvalidArgumentException( '$stage must include a write mode' ); + } + if ( ( $stage & SCHEMA_COMPAT_READ_BOTH ) === 0 ) { + throw new InvalidArgumentException( '$stage must include a read mode' ); + } + + $this->stage = $stage; $this->lang = $lang; } @@ -166,21 +175,21 @@ class CommentStore { public function getFields( $key = null ) { $key = $this->getKey( $key ); $fields = []; - if ( $this->stage === MIGRATION_OLD ) { + if ( ( $this->stage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD ) { $fields["{$key}_text"] = $key; $fields["{$key}_data"] = 'NULL'; $fields["{$key}_cid"] = 'NULL'; - } else { - if ( $this->stage < MIGRATION_NEW ) { + } else { // READ_BOTH or READ_NEW + if ( $this->stage & SCHEMA_COMPAT_READ_OLD ) { $fields["{$key}_old"] = $key; } $tempTableStage = isset( $this->tempTables[$key] ) ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; - if ( $tempTableStage < MIGRATION_NEW ) { + if ( $tempTableStage & SCHEMA_COMPAT_READ_OLD ) { $fields["{$key}_pk"] = $this->tempTables[$key]['joinPK']; } - if ( $tempTableStage > MIGRATION_OLD ) { + if ( $tempTableStage & SCHEMA_COMPAT_READ_NEW ) { $fields["{$key}_id"] = "{$key}_id"; } } @@ -211,21 +220,21 @@ class CommentStore { $fields = []; $joins = []; - if ( $this->stage === MIGRATION_OLD ) { + if ( ( $this->stage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD ) { $fields["{$key}_text"] = $key; $fields["{$key}_data"] = 'NULL'; $fields["{$key}_cid"] = 'NULL'; - } else { - $join = $this->stage === MIGRATION_NEW ? 'JOIN' : 'LEFT JOIN'; + } else { // READ_BOTH or READ_NEW + $join = ( $this->stage & SCHEMA_COMPAT_READ_OLD ) ? 'LEFT JOIN' : 'JOIN'; $tempTableStage = isset( $this->tempTables[$key] ) ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; - if ( $tempTableStage < MIGRATION_NEW ) { + if ( $tempTableStage & SCHEMA_COMPAT_READ_OLD ) { $t = $this->tempTables[$key]; $alias = "temp_$key"; $tables[$alias] = $t['table']; $joins[$alias] = [ $join, "{$alias}.{$t['pk']} = {$t['joinPK']}" ]; - if ( $tempTableStage === MIGRATION_OLD ) { + if ( ( $tempTableStage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD ) { $joinField = "{$alias}.{$t['field']}"; } else { // Nothing hits this code path for now, but will in the future when we set @@ -245,7 +254,7 @@ class CommentStore { $tables[$alias] = 'comment'; $joins[$alias] = [ $join, "{$alias}.comment_id = {$joinField}" ]; - if ( $this->stage === MIGRATION_NEW ) { + if ( ( $this->stage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_NEW ) { $fields["{$key}_text"] = "{$alias}.comment_text"; } else { $fields["{$key}_text"] = "COALESCE( {$alias}.comment_text, $key )"; @@ -282,13 +291,15 @@ class CommentStore { $cid = $row["{$key}_cid"] ?? null; $text = $row["{$key}_text"]; $data = $row["{$key}_data"]; - } elseif ( $this->stage === MIGRATION_OLD ) { + } elseif ( ( $this->stage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD ) { $cid = null; if ( $fallback && isset( $row[$key] ) ) { wfLogWarning( "Using deprecated fallback handling for comment $key" ); $text = $row[$key]; } else { - wfLogWarning( "Missing {$key}_text and {$key}_data fields in row with MIGRATION_OLD" ); + wfLogWarning( + "Missing {$key}_text and {$key}_data fields in row with MIGRATION_OLD / READ_OLD" + ); $text = ''; } $data = null; @@ -296,7 +307,7 @@ class CommentStore { $tempTableStage = isset( $this->tempTables[$key] ) ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; $row2 = null; - if ( $tempTableStage > MIGRATION_OLD && array_key_exists( "{$key}_id", $row ) ) { + if ( ( $tempTableStage & SCHEMA_COMPAT_READ_NEW ) && array_key_exists( "{$key}_id", $row ) ) { if ( !$db ) { throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key and getComment(), but " @@ -311,7 +322,9 @@ class CommentStore { __METHOD__ ); } - if ( !$row2 && $tempTableStage < MIGRATION_NEW && array_key_exists( "{$key}_pk", $row ) ) { + if ( !$row2 && ( $tempTableStage & SCHEMA_COMPAT_READ_OLD ) && + array_key_exists( "{$key}_pk", $row ) + ) { if ( !$db ) { throw new InvalidArgumentException( "\$row does not contain fields needed for comment $key and getComment(), but " @@ -341,7 +354,9 @@ class CommentStore { $cid = $row2->comment_id; $text = $row2->comment_text; $data = $row2->comment_data; - } elseif ( $this->stage < MIGRATION_NEW && array_key_exists( "{$key}_old", $row ) ) { + } elseif ( ( $this->stage & SCHEMA_COMPAT_READ_OLD ) && + array_key_exists( "{$key}_old", $row ) + ) { $cid = null; $text = $row["{$key}_old"]; $data = null; @@ -474,7 +489,7 @@ class CommentStore { # Truncate comment in a Unicode-sensitive manner $comment->text = $this->lang->truncateForVisual( $comment->text, self::COMMENT_CHARACTER_LIMIT ); - if ( $this->stage > MIGRATION_OLD && !$comment->id ) { + if ( ( $this->stage & SCHEMA_COMPAT_WRITE_NEW ) && !$comment->id ) { $dbData = $comment->data; if ( !$comment->message instanceof RawMessage ) { if ( $dbData === null ) { @@ -534,14 +549,14 @@ class CommentStore { $comment = $this->createComment( $dbw, $comment, $data ); - if ( $this->stage <= MIGRATION_WRITE_BOTH ) { + if ( $this->stage & SCHEMA_COMPAT_WRITE_OLD ) { $fields[$key] = $this->lang->truncateForDatabase( $comment->text, 255 ); } - if ( $this->stage >= MIGRATION_WRITE_BOTH ) { + if ( $this->stage & SCHEMA_COMPAT_WRITE_NEW ) { $tempTableStage = isset( $this->tempTables[$key] ) ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; - if ( $tempTableStage <= MIGRATION_WRITE_BOTH ) { + if ( $tempTableStage & SCHEMA_COMPAT_WRITE_OLD ) { $t = $this->tempTables[$key]; $func = __METHOD__; $commentId = $comment->id; @@ -556,7 +571,7 @@ class CommentStore { ); }; } - if ( $tempTableStage >= MIGRATION_WRITE_BOTH ) { + if ( $tempTableStage & SCHEMA_COMPAT_WRITE_NEW ) { $fields["{$key}_id"] = $comment->id; } } @@ -594,7 +609,7 @@ class CommentStore { $tempTableStage = isset( $this->tempTables[$key] ) ? $this->tempTables[$key]['stage'] : MIGRATION_NEW; - if ( $tempTableStage < MIGRATION_WRITE_NEW ) { + if ( $tempTableStage & SCHEMA_COMPAT_WRITE_OLD ) { throw new InvalidArgumentException( "Must use insertWithTempTable() for $key" ); } diff --git a/tests/phpunit/includes/CommentStoreTest.php b/tests/phpunit/includes/CommentStoreTest.php index 9c08b9f94a..57cc073dfc 100644 --- a/tests/phpunit/includes/CommentStoreTest.php +++ b/tests/phpunit/includes/CommentStoreTest.php @@ -73,6 +73,47 @@ class CommentStoreTest extends MediaWikiLangTestCase { return $store; } + /** + * @dataProvider provideConstructor + * @param int $stage + * @param string|null $exceptionMsg + */ + public function testConstructor( $stage, $exceptionMsg ) { + try { + $m = new CommentStore( Language::factory( 'qqx' ), $stage ); + if ( $exceptionMsg !== null ) { + $this->fail( 'Expected exception not thrown' ); + } + $this->assertInstanceOf( CommentStore::class, $m ); + } catch ( InvalidArgumentException $ex ) { + $this->assertSame( $exceptionMsg, $ex->getMessage() ); + } + } + + public static function provideConstructor() { + return [ + [ 0, '$stage must include a write mode' ], + [ SCHEMA_COMPAT_READ_OLD, '$stage must include a write mode' ], + [ SCHEMA_COMPAT_READ_NEW, '$stage must include a write mode' ], + [ SCHEMA_COMPAT_READ_BOTH, '$stage must include a write mode' ], + + [ SCHEMA_COMPAT_WRITE_OLD, '$stage must include a read mode' ], + [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_OLD, null ], + [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_NEW, null ], + [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_BOTH, null ], + + [ SCHEMA_COMPAT_WRITE_NEW, '$stage must include a read mode' ], + [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_OLD, null ], + [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_NEW, null ], + [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_BOTH, null ], + + [ SCHEMA_COMPAT_WRITE_BOTH, '$stage must include a read mode' ], + [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, null ], + [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, null ], + [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_BOTH, null ], + ]; + } + /** * @dataProvider provideGetFields * @param int $stage @@ -115,6 +156,14 @@ class CommentStoreTest extends MediaWikiLangTestCase { MIGRATION_NEW, 'ipb_reason', [ 'ipb_reason_id' => 'ipb_reason_id' ], ], + 'Simple table, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'ipb_reason', + [ 'ipb_reason_text' => 'ipb_reason', 'ipb_reason_data' => 'NULL', 'ipb_reason_cid' => 'NULL' ], + ], + 'Simple table, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'ipb_reason', + [ 'ipb_reason_id' => 'ipb_reason_id' ], + ], 'Revision, old' => [ MIGRATION_OLD, 'rev_comment', @@ -136,6 +185,18 @@ class CommentStoreTest extends MediaWikiLangTestCase { MIGRATION_NEW, 'rev_comment', [ 'rev_comment_pk' => 'rev_id' ], ], + 'Revision, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rev_comment', + [ + 'rev_comment_text' => 'rev_comment', + 'rev_comment_data' => 'NULL', + 'rev_comment_cid' => 'NULL', + ], + ], + 'Revision, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rev_comment', + [ 'rev_comment_pk' => 'rev_id' ], + ], 'Image, old' => [ MIGRATION_OLD, 'img_description', @@ -165,6 +226,20 @@ class CommentStoreTest extends MediaWikiLangTestCase { 'img_description_id' => 'img_description_id' ], ], + 'Image, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'img_description', + [ + 'img_description_text' => 'img_description', + 'img_description_data' => 'NULL', + 'img_description_cid' => 'NULL', + ], + ], + 'Image, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'img_description', + [ + 'img_description_id' => 'img_description_id' + ], + ], ]; } @@ -244,6 +319,30 @@ class CommentStoreTest extends MediaWikiLangTestCase { ], ], ], + 'Simple table, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'ipb_reason', [ + 'tables' => [], + 'fields' => [ + 'ipb_reason_text' => 'ipb_reason', + 'ipb_reason_data' => 'NULL', + 'ipb_reason_cid' => 'NULL', + ], + 'joins' => [], + ], + ], + 'Simple table, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'ipb_reason', [ + 'tables' => [ 'comment_ipb_reason' => 'comment' ], + 'fields' => [ + 'ipb_reason_text' => 'comment_ipb_reason.comment_text', + 'ipb_reason_data' => 'comment_ipb_reason.comment_data', + 'ipb_reason_cid' => 'comment_ipb_reason.comment_id', + ], + 'joins' => [ + 'comment_ipb_reason' => [ 'JOIN', 'comment_ipb_reason.comment_id = ipb_reason_id' ], + ], + ], + ], 'Revision, old' => [ MIGRATION_OLD, 'rev_comment', [ @@ -310,6 +409,35 @@ class CommentStoreTest extends MediaWikiLangTestCase { ], ], ], + 'Revision, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'rev_comment', [ + 'tables' => [], + 'fields' => [ + 'rev_comment_text' => 'rev_comment', + 'rev_comment_data' => 'NULL', + 'rev_comment_cid' => 'NULL', + ], + 'joins' => [], + ], + ], + 'Revision, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'rev_comment', [ + 'tables' => [ + 'temp_rev_comment' => 'revision_comment_temp', + 'comment_rev_comment' => 'comment', + ], + 'fields' => [ + 'rev_comment_text' => 'comment_rev_comment.comment_text', + 'rev_comment_data' => 'comment_rev_comment.comment_data', + 'rev_comment_cid' => 'comment_rev_comment.comment_id', + ], + 'joins' => [ + 'temp_rev_comment' => [ 'JOIN', 'temp_rev_comment.revcomment_rev = rev_id' ], + 'comment_rev_comment' => [ 'JOIN', + 'comment_rev_comment.comment_id = temp_rev_comment.revcomment_comment_id' ], + ], + ], + ], 'Image, old' => [ MIGRATION_OLD, 'img_description', [ @@ -373,6 +501,34 @@ class CommentStoreTest extends MediaWikiLangTestCase { ], ], ], + 'Image, write-both/read-old' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'img_description', [ + 'tables' => [], + 'fields' => [ + 'img_description_text' => 'img_description', + 'img_description_data' => 'NULL', + 'img_description_cid' => 'NULL', + ], + 'joins' => [], + ], + ], + 'Image, write-both/read-new' => [ + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'img_description', [ + 'tables' => [ + 'comment_img_description' => 'comment', + ], + 'fields' => [ + 'img_description_text' => 'comment_img_description.comment_text', + 'img_description_data' => 'comment_img_description.comment_data', + 'img_description_cid' => 'comment_img_description.comment_id', + ], + 'joins' => [ + 'comment_img_description' => [ 'JOIN', + 'comment_img_description.comment_id = img_description_id', + ], + ], + ], + ], ]; } @@ -413,6 +569,15 @@ class CommentStoreTest extends MediaWikiLangTestCase { MIGRATION_NEW ], MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ], MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ], + + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD => [ + MIGRATION_OLD, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, MIGRATION_NEW + ], + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW => [ + MIGRATION_OLD, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, MIGRATION_NEW + ], ]; foreach ( $stages as $writeStage => $possibleReadStages ) { @@ -427,12 +592,12 @@ class CommentStoreTest extends MediaWikiLangTestCase { $fields = $wstore->insert( $this->db, $key, $comment, $data ); } - if ( $writeStage <= MIGRATION_WRITE_BOTH ) { + if ( $writeStage & SCHEMA_COMPAT_WRITE_OLD ) { $this->assertSame( $expect['text'], $fields[$key], "old field, stage=$writeStage" ); } else { $this->assertArrayNotHasKey( $key, $fields, "old field, stage=$writeStage" ); } - if ( $writeStage >= MIGRATION_WRITE_BOTH && !$usesTemp ) { + if ( ( $writeStage & SCHEMA_COMPAT_WRITE_NEW ) && !$usesTemp ) { $this->assertArrayHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" ); } else { $this->assertArrayNotHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" ); @@ -463,13 +628,17 @@ class CommentStoreTest extends MediaWikiLangTestCase { $queryInfo['joins'] ); + $expectForCombination = ( + ( $writeStage & SCHEMA_COMPAT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_OLD || + ( $readStage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD + ) ? $expectOld : $expect; $this->assertComment( - $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect, + $expectForCombination, $rstore->getCommentLegacy( $this->db, $key, $fieldRow ), "w=$writeStage, r=$readStage, from getFields()" ); $this->assertComment( - $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect, + $expectForCombination, $rstore->getComment( $key, $joinRow ), "w=$writeStage, r=$readStage, from getJoin()" ); @@ -503,6 +672,15 @@ class CommentStoreTest extends MediaWikiLangTestCase { MIGRATION_NEW ], MIGRATION_WRITE_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ], MIGRATION_NEW => [ MIGRATION_WRITE_BOTH, MIGRATION_WRITE_NEW, MIGRATION_NEW ], + + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD => [ + MIGRATION_OLD, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, MIGRATION_NEW + ], + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW => [ + MIGRATION_OLD, SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, + SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, MIGRATION_NEW + ], ]; foreach ( $stages as $writeStage => $possibleReadStages ) { @@ -517,12 +695,12 @@ class CommentStoreTest extends MediaWikiLangTestCase { $fields = $wstore->insert( $this->db, $comment, $data ); } - if ( $writeStage <= MIGRATION_WRITE_BOTH ) { + if ( $writeStage & SCHEMA_COMPAT_WRITE_OLD ) { $this->assertSame( $expect['text'], $fields[$key], "old field, stage=$writeStage" ); } else { $this->assertArrayNotHasKey( $key, $fields, "old field, stage=$writeStage" ); } - if ( $writeStage >= MIGRATION_WRITE_BOTH && !$usesTemp ) { + if ( ( $writeStage & SCHEMA_COMPAT_WRITE_NEW ) && !$usesTemp ) { $this->assertArrayHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" ); } else { $this->assertArrayNotHasKey( "{$key}_id", $fields, "new field, stage=$writeStage" ); @@ -553,13 +731,17 @@ class CommentStoreTest extends MediaWikiLangTestCase { $queryInfo['joins'] ); + $expectForCombination = ( + ( $writeStage & SCHEMA_COMPAT_WRITE_BOTH ) === SCHEMA_COMPAT_WRITE_OLD || + ( $readStage & SCHEMA_COMPAT_READ_BOTH ) === SCHEMA_COMPAT_READ_OLD + ) ? $expectOld : $expect; $this->assertComment( - $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect, + $expectForCombination, $rstore->getCommentLegacy( $this->db, $fieldRow ), "w=$writeStage, r=$readStage, from getFields()" ); $this->assertComment( - $writeStage === MIGRATION_OLD || $readStage === MIGRATION_OLD ? $expectOld : $expect, + $expectForCombination, $rstore->getComment( $joinRow ), "w=$writeStage, r=$readStage, from getJoin()" ); @@ -725,6 +907,9 @@ class CommentStoreTest extends MediaWikiLangTestCase { 'MIGRATION_WRITE_BOTH' => [ MIGRATION_WRITE_BOTH ], 'MIGRATION_WRITE_NEW' => [ MIGRATION_WRITE_NEW ], 'MIGRATION_NEW' => [ MIGRATION_NEW ], + + 'SCHEMA_COMPAT write-both/read-old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD ], + 'SCHEMA_COMPAT write-both/read-new' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW ], ]; } -- 2.20.1