Fix the CI failures in the uninstaller work
CI / Coding Standards (pull_request) Successful in 28s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.1) (pull_request) Successful in 38s
CI / Tests (PHP 8.3) (pull_request) Successful in 40s
CI / Tests (PHP 8.2) (pull_request) Successful in 49s
CI / Static Analysis (pull_request) Successful in 1m0s
CI / Tests (PHP 8.5) (pull_request) Successful in 57s
CI / Build Plugin Zip (pull_request) Skipped
CI / Coding Standards (pull_request) Successful in 28s
CI / No Debug Code (pull_request) Successful in 3s
CI / Tests (PHP 8.1) (pull_request) Successful in 38s
CI / Tests (PHP 8.3) (pull_request) Successful in 40s
CI / Tests (PHP 8.2) (pull_request) Successful in 49s
CI / Static Analysis (pull_request) Successful in 1m0s
CI / Tests (PHP 8.5) (pull_request) Successful in 57s
CI / Build Plugin Zip (pull_request) Skipped
Both were mine, and both were in code the earlier commit could not run. The four test failures shared one cause: UninstallerTest stubbed get_option with an arrow function, which captures by value, so every read answered from a snapshot of the options taken at setUp — before the test set any and before the run wrote any. Every assertion that depended on reading back what had just been written therefore saw an empty store. The file's other stubs already use by-reference closures; this one now does too. The phpcs error is WordPress.DB.PreparedSQL.NotPrepared on the table drop. The sniff cannot follow $sql across the null guard that PHPStan requires (prepare() is nullable), and unlike the repositories — which call through a typed $this->db property the sniff does not track at all — the uninstaller calls the global $wpdb, so the sniff sees it. Silenced explicitly, with the reason. composer test (996 tests, 2871 assertions), composer lint and composer cs all pass locally on PHP 8.4. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+1
-1
@@ -182,7 +182,7 @@ class Uninstaller {
|
||||
$sql = $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $wpdb->prefix . $table );
|
||||
|
||||
if ( null !== $sql ) {
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- uninstall drops the plugin's own tables; the names come from Schema::TABLES, not from input.
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- $sql is the prepared statement two lines up; the sniff cannot follow it across the null guard, which PHPStan requires because prepare() is nullable. The only interpolated value is a Schema::TABLES constant.
|
||||
$wpdb->query( $sql );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,13 @@ class UninstallerTest extends TestCase
|
||||
$rolesRemoved = &$this->rolesRemoved;
|
||||
$hooksCleared = &$this->hooksCleared;
|
||||
|
||||
// A regular closure, not an arrow fn: arrow functions capture by value,
|
||||
// so every read would answer from a snapshot of the options taken at
|
||||
// setUp — before the test set any, and before the run wrote any.
|
||||
Functions\when('get_option')->alias(
|
||||
static fn(string $key, mixed $default = false): mixed => $options[$key] ?? $default
|
||||
static function (string $key, mixed $default = false) use (&$options): mixed {
|
||||
return $options[$key] ?? $default;
|
||||
}
|
||||
);
|
||||
Functions\when('update_option')->alias(
|
||||
static function (string $key, mixed $value) use (&$options): bool {
|
||||
|
||||
Reference in New Issue
Block a user