Skip to content

Commit

Permalink
Build/Test Tools: Add initial tests for the WP_Filesystem_Direct cl…
Browse files Browse the repository at this point in the history
…ass.

Since `WP_Filesystem_Direct` is by far the most used filesystem abstraction class, this facilitates future changes with sufficient test coverage.

Props swissspidy, costdev, mukesh27.
Fixes #57774.

git-svn-id: https://develop.svn.wordpress.org/trunk@57753 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
swissspidy committed Mar 2, 2024
1 parent c828ba1 commit 5bf25d8
Show file tree
Hide file tree
Showing 26 changed files with 2,193 additions and 0 deletions.
50 changes: 50 additions & 0 deletions tests/phpunit/tests/filesystem/wpFilesystemDirect/atime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
* Tests for the WP_Filesystem_Direct::atime() method.
*
* @package WordPress
*/

require_once __DIR__ . '/base.php';

/**
* @group admin
* @group filesystem
* @group filesystem-direct
*
* @covers WP_Filesystem_Direct::atime
*/
class Tests_Filesystem_WpFilesystemDirect_Atime extends WP_Filesystem_Direct_UnitTestCase {

/**
* Tests that `WP_Filesystem_Direct::atime()`
* returns an integer for a path that exists.
*
* @ticket 57774
*
* @dataProvider data_paths_that_exist
*
* @param string $path The path.
*/
public function test_should_determine_accessed_time( $path ) {
$path = self::$file_structure['test_dir']['path'] . $path;

$this->assertIsInt( self::$filesystem->atime( $path ) );
}

/**
* Tests that `WP_Filesystem_Direct::atime()`
* returns false for a path that does not exist.
*
* @ticket 57774
*
* @dataProvider data_paths_that_do_not_exist
*
* @param string $path The path.
*/
public function test_should_return_false_for_a_path_that_does_not_exist( $path ) {
$path = self::$file_structure['test_dir']['path'] . $path;

$this->assertFalse( self::$filesystem->atime( $path ) );
}
}
197 changes: 197 additions & 0 deletions tests/phpunit/tests/filesystem/wpFilesystemDirect/base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
<?php

/**
* Base class for WP_Filesystem_Direct tests.
*
* @package WordPress
*/
abstract class WP_Filesystem_Direct_UnitTestCase extends WP_UnitTestCase {

/**
* The filesystem object.
*
* @var WP_Filesystem_Direct
*/
protected static $filesystem;

/**
* The file structure for tests.
*
* @var array
*/
protected static $file_structure = array();

/**
* Sets up test assets before the class.
*/
public static function set_up_before_class() {
parent::set_up_before_class();

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

self::$filesystem = new WP_Filesystem_Direct( null );

$filesystem_data_dir = wp_normalize_path( DIR_TESTDATA . '/filesystem/' );
if ( ! file_exists( $filesystem_data_dir ) ) {
mkdir( $filesystem_data_dir );
}

/*
* These must be created during the tests as they may be modified or deleted
* during testing, either intentionally or accidentally as a result of test failure.
*/
$test_data_root_dir = $filesystem_data_dir . 'filesystem_api/';
$test_data_dir = $test_data_root_dir . 'wpFilesystemDirect/';

self::$file_structure = array(
// Directories first.
'test_dir_root' => array(
'type' => 'd',
'path' => $test_data_root_dir,
),
'test_dir' => array(
'type' => 'd',
'path' => $test_data_dir,
),
'subdir' => array(
'type' => 'd',
'path' => $test_data_dir . 'subdir/',
),

// Then files.
'visible_file' => array(
'type' => 'f',
'path' => $test_data_dir . 'a_file_that_exists.txt',
'contents' => "Contents of a file.\r\nNext line of a file.\r\n",
),
'hidden_file' => array(
'type' => 'f',
'path' => $test_data_dir . '.a_hidden_file',
'contents' => "A hidden file.\r\n",
),
'subfile' => array(
'type' => 'f',
'path' => $test_data_dir . 'subdir/subfile.txt',
'contents' => "A file in a subdirectory.\r\n",
),
);
}

/**
* Creates any missing test assets before each test.
*/
public function set_up() {
parent::set_up();

foreach ( self::$file_structure as $entry ) {
if ( 'd' === $entry['type'] ) {
$this->create_directory_if_needed( $entry['path'] );
} elseif ( 'f' === $entry['type'] ) {
$this->create_file_if_needed(
$entry['path'],
isset( $entry['contents'] ) ? $entry['contents'] : ''
);
}
}
}

/**
* Removes any existing test assets after each test.
*/
public function tear_down() {
foreach ( array_reverse( self::$file_structure ) as $entry ) {
if ( ! file_exists( $entry['path'] ) ) {
continue;
}

if ( 'f' === $entry['type'] ) {
unlink( $entry['path'] );
} elseif ( 'd' === $entry['type'] ) {
rmdir( $entry['path'] );
}
}

parent::tear_down();
}

/**
* Creates a directory if it doesn't already exist.
*
* @throws Exception If the path already exists as a file.
*
* @param string $path The path to the directory.
*/
public function create_directory_if_needed( $path ) {
if ( file_exists( $path ) ) {
if ( is_file( $path ) ) {
throw new Exception( "$path already exists as a file." );
}

return;
}

mkdir( $path );
}

/**
* Creates a file if it doesn't already exist.
*
* @throws Exception If the path already exists as a directory.
*
* @param string $path The path to the file.
* @param string $contents Optional. The contents of the file. Default empty string.
*/
public function create_file_if_needed( $path, $contents = '' ) {
if ( file_exists( $path ) ) {
if ( is_dir( $path ) ) {
throw new Exception( "$path already exists as a directory." );
}

return;
}

file_put_contents( $path, $contents );
}

/**
* Determines whether the operating system is Windows.
*
* @return bool Whether the operating system is Windows.
*/
public static function is_windows() {
return 'WIN' === substr( PHP_OS, 0, 3 );
}

/**
* Data provider.
*
* @return array[]
*/
public function data_paths_that_exist() {
return array(
'a file that exists' => array(
'path' => 'a_file_that_exists.txt',
),
'a directory that exists' => array(
'path' => '',
),
);
}

/**
* Data provider.
*
* @return array[]
*/
public function data_paths_that_do_not_exist() {
return array(
'a file that does not exist' => array(
'path' => 'a_file_that_does_not_exist.txt',
),
'a directory that does not exist' => array(
'path' => 'a_directory_that_does_not_exist',
),
);
}
}
95 changes: 95 additions & 0 deletions tests/phpunit/tests/filesystem/wpFilesystemDirect/chdir.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
/**
* Tests for the WP_Filesystem_Direct::chdir() method.
*
* @package WordPress
*/

require_once __DIR__ . '/base.php';

/**
* @group admin
* @group filesystem
* @group filesystem-direct
*
* @covers WP_Filesystem_Direct::chdir
*/
class Tests_Filesystem_WpFilesystemDirect_Chdir extends WP_Filesystem_Direct_UnitTestCase {

/**
* Tests that `WP_Filesystem_Direct::chdir()`
* returns false for a path that does not exist.
*
* @ticket 57774
*
* @dataProvider data_should_fail_to_change_directory
*
* @param string $path The path.
*/
public function test_should_fail_to_change_directory( $path ) {
$original_cwd = self::$filesystem->cwd();
$path = wp_normalize_path( realpath( self::$file_structure['test_dir']['path'] ) ) . $path;
$chdir_result = self::$filesystem->chdir( $path );
$cwd_result = self::$filesystem->cwd();

// Reset the current working directory.
self::$filesystem->chdir( $original_cwd );

$this->assertFalse(
$chdir_result,
'Changing working directory succeeded.'
);

$this->assertSame(
$original_cwd,
$cwd_result,
'The current working directory was changed.'
);
}

/**
* Data provider.
*
* @return array[]
*/
public function data_should_fail_to_change_directory() {
return array(
'a file that exists' => array(
'path' => 'a_file_that_exists.txt',
),
'a file that does not exist' => array(
'path' => 'a_file_that_does_not_exist.txt',
),
'a directory that does not exist' => array(
'path' => 'a_directory_that_does_not_exist',
),
);
}

/**
* Tests that `WP_Filesystem_Direct::chdir()` changes to
* an existing directory.
*
* @ticket 57774
*/
public function test_should_change_directory() {
$original_cwd = self::$filesystem->cwd();
$path = wp_normalize_path( realpath( self::$file_structure['test_dir']['path'] ) );
$chdir_result = self::$filesystem->chdir( $path );
$cwd_result = self::$filesystem->cwd();

// Reset the current working directory.
self::$filesystem->chdir( $original_cwd );

$this->assertTrue(
$chdir_result,
'Changing working directory failed.'
);

$this->assertSame(
$path,
$cwd_result,
'The current working directory was incorrect.'
);
}
}
32 changes: 32 additions & 0 deletions tests/phpunit/tests/filesystem/wpFilesystemDirect/chgrp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Tests for the WP_Filesystem_Direct::chgrp() method.
*
* @package WordPress
*/

require_once __DIR__ . '/base.php';

/**
* @group admin
* @group filesystem
* @group filesystem-direct
*
* @covers WP_Filesystem_Direct::chgrp
*/
class Tests_Filesystem_WpFilesystemDirect_Chgrp extends WP_Filesystem_Direct_UnitTestCase {

/**
* Tests that `WP_Filesystem_Direct::chgrp()`
* returns false for a path that does not exist.
*
* @ticket 57774
*
* @dataProvider data_paths_that_do_not_exist
*
* @param string $path The path.
*/
public function test_should_fail_to_change_file_group( $path ) {
$this->assertFalse( self::$filesystem->chgrp( self::$file_structure['test_dir']['path'] . $path, 0 ) );
}
}
Loading

0 comments on commit 5bf25d8

Please sign in to comment.