diff --git a/phpcs.xml b/phpcs.xml
index 417f01c..abe6fa4 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -6,9 +6,6 @@
-
-
-
@@ -17,6 +14,12 @@
+
+ */tests/Unit/*Test.php
+
+
+ */tests/Unit/*Test.php
+
@@ -27,6 +30,8 @@
*/vendor/*
*/.github/*
+ */tests/bootstrap.php
scripts
+ tests/Unit
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 9282139..2387ceb 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -7,7 +7,7 @@
>
- tests/Unit
+ tests/Unit
diff --git a/scripts/bump-plugin-version.php b/scripts/bump-plugin-version.php
index 611e4ad..fa0c40c 100644
--- a/scripts/bump-plugin-version.php
+++ b/scripts/bump-plugin-version.php
@@ -30,14 +30,14 @@ function is_bump_plugin_version_entrypoint( array $argv ): bool {
*/
function bump_plugin_version_cli( array $argv ): int {
if ( 'cli' !== PHP_SAPI ) {
- fwrite( STDERR, "This script must run from the command line.\n" );
+ fwrite( STDERR, "This script must run from the command line.\n" ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite -- CLI scripts write status messages to STDERR.
return 1;
}
$root = getcwd();
if ( false === $root ) {
- fwrite( STDERR, "Unable to determine repository root.\n" );
+ fwrite( STDERR, "Unable to determine repository root.\n" ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite -- CLI scripts write status messages to STDERR.
return 1;
}
@@ -45,10 +45,10 @@ function bump_plugin_version_cli( array $argv ): int {
try {
$new_version = bump_plugin_version( $root, $bump_type );
- fwrite( STDOUT, "Bumped plugin version to {$new_version}\n" );
+ fwrite( STDOUT, "Bumped plugin version to {$new_version}\n" ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite -- CLI scripts write status messages to STDOUT.
return 0;
} catch ( Throwable $throwable ) {
- fwrite( STDERR, $throwable->getMessage() . "\n" );
+ fwrite( STDERR, $throwable->getMessage() . "\n" ); // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_fwrite -- CLI scripts write status messages to STDERR.
return 1;
}
}
@@ -143,6 +143,7 @@ function bump_plugin_version( string $root, string $bump_type ): string {
}
foreach ( $writes as $path => $contents ) {
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_file_put_contents -- This CLI helper intentionally updates version metadata files.
if ( file_put_contents( $path, $contents ) === false ) {
throw new RuntimeException( "Unable to write {$path}" );
}
@@ -194,6 +195,7 @@ function path_join( string $base, string $path ): string {
* @throws RuntimeException When the file cannot be read.
*/
function read_required_file( string $path ): string {
+ // phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown -- Local filesystem reads are this CLI helper's purpose.
$contents = file_get_contents( $path );
if ( false === $contents ) {
diff --git a/tests/Unit/BumpPluginVersionTest.php b/tests/Unit/BumpPluginVersionTest.php
index c206b79..6e61e5a 100644
--- a/tests/Unit/BumpPluginVersionTest.php
+++ b/tests/Unit/BumpPluginVersionTest.php
@@ -1,4 +1,10 @@
*/
private array $temp_dirs = [];
+ /**
+ * Previous environment values.
+ *
+ * @var array
+ */
+ private array $previous_env = [];
+
+ /**
+ * Clean temporary fixtures and environment.
+ */
protected function tearDown(): void {
foreach ( $this->temp_dirs as $dir ) {
$this->delete_tree( $dir );
}
- foreach ( [ 'PLUGIN_FILE', 'VERSION_CONSTANT', 'PACKAGE_FILE', 'POT_FILE', 'POT_PROJECT', 'BLOCK_JSON_GLOB' ] as $name ) {
- putenv( $name );
+ foreach ( $this->previous_env as $name => $previous_value ) {
+ if ( false !== $previous_value ) {
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv -- Tests isolate CLI helper environment variables.
+ putenv( "{$name}={$previous_value}" );
+ } else {
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv -- Tests isolate CLI helper environment variables.
+ putenv( $name );
+ }
}
+
+ $this->previous_env = [];
}
+ /**
+ * Test configured version surfaces are bumped together.
+ *
+ * @covers ::bump_plugin_version
+ */
public function test_bump_updates_all_configured_version_surfaces(): void {
$root = $this->make_fixture(
[
- 'demo-plugin.php' => " "{\n\t\"name\": \"demo-plugin\",\n\t\"version\": \"0.1.2\"\n}\n",
- 'languages/demo.pot' => "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Demo plugin 0.1.2\\n\"\n",
+ 'demo-plugin.php' => " "{\n\t\"name\": \"demo-plugin\",\n\t\"version\": \"0.1.2\"\n}\n",
+ 'languages/demo.pot' => "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Demo plugin 0.1.2\\n\"\n",
'src/example/block.json' => "{\n\t\"name\": \"demo/example\",\n\t\"version\": \"0.1.2\"\n}\n",
]
);
@@ -44,14 +81,19 @@ public function test_bump_updates_all_configured_version_surfaces(): void {
]
);
- self::assertSame( '0.2.0', bump_plugin_version( $root, 'minor' ) );
- self::assertStringContainsString( "* Version: 0.2.0\n", file_get_contents( $root . '/demo-plugin.php' ) ?: '' );
- self::assertStringContainsString( "define( 'DEMO_PLUGIN_VERSION', '0.2.0' );", file_get_contents( $root . '/demo-plugin.php' ) ?: '' );
- self::assertStringContainsString( '"version": "0.2.0"', file_get_contents( $root . '/package.json' ) ?: '' );
- self::assertStringContainsString( 'Project-Id-Version: Demo plugin 0.2.0\\n', file_get_contents( $root . '/languages/demo.pot' ) ?: '' );
- self::assertStringContainsString( '"version": "0.2.0"', file_get_contents( $root . '/src/example/block.json' ) ?: '' );
+ self::assertSame( '0.2.0', bump_plugin_version( $root, 'minor' ), 'Minor bumps should update the returned version.' );
+ self::assertStringContainsString( "* Version: 0.2.0\n", read_required_file( $root . '/demo-plugin.php' ), 'Plugin headers should be bumped.' );
+ self::assertStringContainsString( "define( 'DEMO_PLUGIN_VERSION', '0.2.0' );", read_required_file( $root . '/demo-plugin.php' ), 'Version constants should be bumped.' );
+ self::assertStringContainsString( '"version": "0.2.0"', read_required_file( $root . '/package.json' ), 'Package versions should be bumped.' );
+ self::assertStringContainsString( 'Project-Id-Version: Demo plugin 0.2.0\\n', read_required_file( $root . '/languages/demo.pot' ), 'POT project versions should be bumped.' );
+ self::assertStringContainsString( '"version": "0.2.0"', read_required_file( $root . '/src/example/block.json' ), 'Block metadata versions should be bumped.' );
}
+ /**
+ * Test prerelease versions are rejected.
+ *
+ * @covers ::bump_plugin_version
+ */
public function test_bump_rejects_prerelease_versions(): void {
$root = $this->make_fixture(
[
@@ -70,6 +112,11 @@ public function test_bump_rejects_prerelease_versions(): void {
bump_plugin_version( $root, 'patch' );
}
+ /**
+ * Test ambiguous version surfaces fail closed.
+ *
+ * @covers ::bump_plugin_version
+ */
public function test_bump_fails_closed_when_a_surface_is_ambiguous(): void {
$root = $this->make_fixture(
[
@@ -89,10 +136,13 @@ public function test_bump_fails_closed_when_a_surface_is_ambiguous(): void {
}
/**
+ * Make a temporary fixture directory.
+ *
* @param array $files Files keyed by relative path.
*/
private function make_fixture( array $files ): string {
$root = sys_get_temp_dir() . '/wpvdb-scripts-test-' . bin2hex( random_bytes( 6 ) );
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.directory_mkdir -- Tests create isolated temporary fixture directories.
mkdir( $root, 0777, true );
$this->temp_dirs[] = $root;
@@ -100,8 +150,10 @@ private function make_fixture( array $files ): string {
$path = $root . '/' . $relative_path;
$dir = dirname( $path );
if ( ! is_dir( $dir ) ) {
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.directory_mkdir -- Tests create isolated temporary fixture directories.
mkdir( $dir, 0777, true );
}
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_file_put_contents -- Tests create isolated temporary fixture files.
file_put_contents( $path, $contents );
}
@@ -109,14 +161,26 @@ private function make_fixture( array $files ): string {
}
/**
+ * Configure environment variables for the helper.
+ *
* @param array $env Environment values.
*/
private function configure_env( array $env ): void {
foreach ( $env as $name => $value ) {
+ if ( ! array_key_exists( $name, $this->previous_env ) ) {
+ $this->previous_env[ $name ] = getenv( $name );
+ }
+
+ // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv -- Tests configure CLI helper environment variables.
putenv( "{$name}={$value}" );
}
}
+ /**
+ * Delete a temporary fixture tree.
+ *
+ * @param string $path Directory path.
+ */
private function delete_tree( string $path ): void {
if ( ! is_dir( $path ) ) {
return;
@@ -128,9 +192,11 @@ private function delete_tree( string $path ): void {
);
foreach ( $iterator as $item ) {
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.directory_rmdir, WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_unlink -- Tests clean isolated temporary fixtures.
$item->isDir() ? rmdir( $item->getPathname() ) : unlink( $item->getPathname() );
}
+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.directory_rmdir -- Tests clean isolated temporary fixture directories.
rmdir( $path );
}
}