Skip to content

Commit

Permalink
Tests: Add test resources for AspireUpdate\Debug (#244)
Browse files Browse the repository at this point in the history
* Tests: Introduce Debug_UnitTestCase and AP_FakeFilesystem.

* Coding Standards: Exclude test files from filesystem sniffs.

* Coding Standards: Exclude all test PHP files, not just test classes.
  • Loading branch information
costdev authored Dec 19, 2024
1 parent ef25893 commit 056914f
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 1 deletion.
18 changes: 17 additions & 1 deletion phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,25 @@

<!-- Exclude test classes from naming conventions. -->
<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<exclude-pattern>/tests/phpunit/tests/*</exclude-pattern>
<exclude-pattern>/tests/phpunit/*</exclude-pattern>
</rule>
<rule ref="WordPress.Files.FileName.NotHyphenatedLowercase">
<exclude-pattern>/tests/phpunit/*</exclude-pattern>
</rule>

<!-- Exclude test files from overriding globals sniff. -->
<rule ref="WordPress.WP.GlobalVariablesOverride.Prohibited">
<exclude-pattern>/tests/phpunit/tests/*</exclude-pattern>
</rule>

<!-- Exclude test files from some filesystem sniffs. -->
<rule ref="WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents">
<exclude-pattern>/tests/phpunit/*</exclude-pattern>
</rule>
<rule ref="WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents">
<exclude-pattern>/tests/phpunit/*</exclude-pattern>
</rule>
<rule ref="WordPress.WP.AlternativeFunctions.unlink_unlink">
<exclude-pattern>/tests/phpunit/*</exclude-pattern>
</rule>
</ruleset>
4 changes: 4 additions & 0 deletions tests/phpunit/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,9 @@ function _manually_load_plugin() {
// Start up the WP testing environment.
require "{$_tests_dir}/includes/bootstrap.php";

// Load unit test mocks and fakes.
require __DIR__ . '/includes/class-ap-fake-filesystem.php';

// Load unit test abstract classes.
require __DIR__ . '/includes/AdminSettings_UnitTestCase.php';
require __DIR__ . '/includes/Debug_UnitTestCase.php';
116 changes: 116 additions & 0 deletions tests/phpunit/includes/Debug_UnitTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php
/**
* Abstract base test class for \AspireUpdate\Debug.
*
* All \AspireUpdate\Debug unit tests should inherit from this class.
*/
abstract class Debug_UnitTestCase extends WP_UnitTestCase {
/**
* The path to the log file.
*
* @var string
*/
protected static $log_file;

/**
* Previously created filesystems.
*
* @var array
*/
protected static $filesystems = [];

/**
* The original value of $wp_filesystem before any tests run.
*
* @var WP_Filesystem_Base|null|false False if not already set.
*/
protected static $default_filesystem;

/**
* Gets the log file's path, and deletes if it exists before any tests run.
* Backs up the default filesystem.
*
* @return void
*/
public static function set_up_before_class() {
parent::set_up_before_class();

$get_file_path = new ReflectionMethod(
'AspireUpdate\Debug',
'get_file_path'
);

$get_file_path->setAccessible( true );
self::$log_file = $get_file_path->invoke( null );
$get_file_path->setAccessible( false );

if ( file_exists( self::$log_file ) ) {
unlink( self::$log_file );
}

if ( isset( $GLOBALS['wp_filesystem'] ) ) {
self::$default_filesystem = $GLOBALS['wp_filesystem'];
} else {
self::$default_filesystem = false;
}
}

/**
* Filters the filesystem method before each test runs.
*
* Filters are removed in the tear_down() parent method.
*
* @return void
*/
public function set_up() {
parent::set_up();

add_filter(
'filesystem_method',
static function () {
return 'direct';
}
);
}

/**
* Delete the log file and restores the filesystem after each test runs.
*
* @return void
*/
public function tear_down() {
if ( file_exists( self::$log_file ) ) {
unlink( self::$log_file );
}

if ( false === self::$default_filesystem ) {
unset( $GLOBALS['wp_filesystem'] );
} else {
$GLOBALS['wp_filesystem'] = self::$default_filesystem;
}

parent::tear_down();
}

/**
* Creates a fake filesystem.
*
* @param bool|null $exists Whether paths should exist.
* Default null uses default implemenation.
* @param bool|null $is_readable Whether paths should be readable.
* Default null uses default implemenation.
* @param bool|null $is_writable Whether paths should be writable.
* Default null uses default implemenation.
*/
public function get_fake_filesystem( $exists = null, $is_readable = null, $is_writable = null ) {
$hash = ( null === $exists ? '-1' : (int) $exists ) . ',' .
( null === $is_readable ? '-1' : (int) $is_readable ) . ',' .
( null === $is_writable ? '-1' : (int) $is_writable );

if ( ! isset( self::$filesystems[ $hash ] ) ) {
self::$filesystems[ $hash ] = new AP_FakeFilesystem( $exists, $is_readable, $is_writable );
}

return self::$filesystems[ $hash ];
}
}
82 changes: 82 additions & 0 deletions tests/phpunit/includes/class-ap-fake-filesystem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';

class AP_FakeFilesystem extends WP_Filesystem_Direct {
/**
* Whether paths should exist.
*
* @var bool|null
*/
private $exists;

/**
* Whether paths should be readable.
*
* @var bool|null
*/
private $is_readable;

/**
* Whether paths should be writable.
*
* @var bool|null
*/
private $is_writable;

/**
* Contructor.
*
* @param bool|null $exists Whether paths should exist.
* Default null to use parent implementation.
* @param bool|null $is_readable Whether paths should be readable.
* Default null to use parent implementation.
* @param bool|null $is_writable Whether paths should be writable.
* Default null to use parent implementation.
*/
public function __construct( $exists = null, $is_readable = null, $is_writable = null ) {
$this->exists = $exists;
$this->is_readable = $is_readable;
$this->is_writable = $is_writable;
}

/**
* Checks whether a path exists.
*
* @param string $path The path to check.
* @return bool Whether the path exists.
*/
public function exists( $path ) {
if ( null === $this->exists ) {
return parent::exists( $path );
}
return $this->exists;
}

/**
* Checks whether a path is readable.
*
* @param string $path The path to check.
* @return bool Whether the path is readable.
*/
public function is_readable( $path ) {
if ( null === $this->is_readable ) {
return parent::is_readable( $path );
}
return $this->is_readable;
}

/**
* Checks whether a path is writable.
*
* @param string $path The path to check.
* @return bool Whether the path is writable.
*/
public function is_writable( $path ) {
if ( null === $this->is_writable ) {
return parent::is_writable( $path );
}
return $this->is_writable;
}
}

0 comments on commit 056914f

Please sign in to comment.