Skip to content

Commit 5bf25d8

Browse files
committed
Build/Test Tools: Add initial tests for the WP_Filesystem_Direct class.
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
1 parent c828ba1 commit 5bf25d8

26 files changed

Lines changed: 2193 additions & 0 deletions
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Tests for the WP_Filesystem_Direct::atime() method.
4+
*
5+
* @package WordPress
6+
*/
7+
8+
require_once __DIR__ . '/base.php';
9+
10+
/**
11+
* @group admin
12+
* @group filesystem
13+
* @group filesystem-direct
14+
*
15+
* @covers WP_Filesystem_Direct::atime
16+
*/
17+
class Tests_Filesystem_WpFilesystemDirect_Atime extends WP_Filesystem_Direct_UnitTestCase {
18+
19+
/**
20+
* Tests that `WP_Filesystem_Direct::atime()`
21+
* returns an integer for a path that exists.
22+
*
23+
* @ticket 57774
24+
*
25+
* @dataProvider data_paths_that_exist
26+
*
27+
* @param string $path The path.
28+
*/
29+
public function test_should_determine_accessed_time( $path ) {
30+
$path = self::$file_structure['test_dir']['path'] . $path;
31+
32+
$this->assertIsInt( self::$filesystem->atime( $path ) );
33+
}
34+
35+
/**
36+
* Tests that `WP_Filesystem_Direct::atime()`
37+
* returns false for a path that does not exist.
38+
*
39+
* @ticket 57774
40+
*
41+
* @dataProvider data_paths_that_do_not_exist
42+
*
43+
* @param string $path The path.
44+
*/
45+
public function test_should_return_false_for_a_path_that_does_not_exist( $path ) {
46+
$path = self::$file_structure['test_dir']['path'] . $path;
47+
48+
$this->assertFalse( self::$filesystem->atime( $path ) );
49+
}
50+
}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
<?php
2+
3+
/**
4+
* Base class for WP_Filesystem_Direct tests.
5+
*
6+
* @package WordPress
7+
*/
8+
abstract class WP_Filesystem_Direct_UnitTestCase extends WP_UnitTestCase {
9+
10+
/**
11+
* The filesystem object.
12+
*
13+
* @var WP_Filesystem_Direct
14+
*/
15+
protected static $filesystem;
16+
17+
/**
18+
* The file structure for tests.
19+
*
20+
* @var array
21+
*/
22+
protected static $file_structure = array();
23+
24+
/**
25+
* Sets up test assets before the class.
26+
*/
27+
public static function set_up_before_class() {
28+
parent::set_up_before_class();
29+
30+
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
31+
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
32+
33+
self::$filesystem = new WP_Filesystem_Direct( null );
34+
35+
$filesystem_data_dir = wp_normalize_path( DIR_TESTDATA . '/filesystem/' );
36+
if ( ! file_exists( $filesystem_data_dir ) ) {
37+
mkdir( $filesystem_data_dir );
38+
}
39+
40+
/*
41+
* These must be created during the tests as they may be modified or deleted
42+
* during testing, either intentionally or accidentally as a result of test failure.
43+
*/
44+
$test_data_root_dir = $filesystem_data_dir . 'filesystem_api/';
45+
$test_data_dir = $test_data_root_dir . 'wpFilesystemDirect/';
46+
47+
self::$file_structure = array(
48+
// Directories first.
49+
'test_dir_root' => array(
50+
'type' => 'd',
51+
'path' => $test_data_root_dir,
52+
),
53+
'test_dir' => array(
54+
'type' => 'd',
55+
'path' => $test_data_dir,
56+
),
57+
'subdir' => array(
58+
'type' => 'd',
59+
'path' => $test_data_dir . 'subdir/',
60+
),
61+
62+
// Then files.
63+
'visible_file' => array(
64+
'type' => 'f',
65+
'path' => $test_data_dir . 'a_file_that_exists.txt',
66+
'contents' => "Contents of a file.\r\nNext line of a file.\r\n",
67+
),
68+
'hidden_file' => array(
69+
'type' => 'f',
70+
'path' => $test_data_dir . '.a_hidden_file',
71+
'contents' => "A hidden file.\r\n",
72+
),
73+
'subfile' => array(
74+
'type' => 'f',
75+
'path' => $test_data_dir . 'subdir/subfile.txt',
76+
'contents' => "A file in a subdirectory.\r\n",
77+
),
78+
);
79+
}
80+
81+
/**
82+
* Creates any missing test assets before each test.
83+
*/
84+
public function set_up() {
85+
parent::set_up();
86+
87+
foreach ( self::$file_structure as $entry ) {
88+
if ( 'd' === $entry['type'] ) {
89+
$this->create_directory_if_needed( $entry['path'] );
90+
} elseif ( 'f' === $entry['type'] ) {
91+
$this->create_file_if_needed(
92+
$entry['path'],
93+
isset( $entry['contents'] ) ? $entry['contents'] : ''
94+
);
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Removes any existing test assets after each test.
101+
*/
102+
public function tear_down() {
103+
foreach ( array_reverse( self::$file_structure ) as $entry ) {
104+
if ( ! file_exists( $entry['path'] ) ) {
105+
continue;
106+
}
107+
108+
if ( 'f' === $entry['type'] ) {
109+
unlink( $entry['path'] );
110+
} elseif ( 'd' === $entry['type'] ) {
111+
rmdir( $entry['path'] );
112+
}
113+
}
114+
115+
parent::tear_down();
116+
}
117+
118+
/**
119+
* Creates a directory if it doesn't already exist.
120+
*
121+
* @throws Exception If the path already exists as a file.
122+
*
123+
* @param string $path The path to the directory.
124+
*/
125+
public function create_directory_if_needed( $path ) {
126+
if ( file_exists( $path ) ) {
127+
if ( is_file( $path ) ) {
128+
throw new Exception( "$path already exists as a file." );
129+
}
130+
131+
return;
132+
}
133+
134+
mkdir( $path );
135+
}
136+
137+
/**
138+
* Creates a file if it doesn't already exist.
139+
*
140+
* @throws Exception If the path already exists as a directory.
141+
*
142+
* @param string $path The path to the file.
143+
* @param string $contents Optional. The contents of the file. Default empty string.
144+
*/
145+
public function create_file_if_needed( $path, $contents = '' ) {
146+
if ( file_exists( $path ) ) {
147+
if ( is_dir( $path ) ) {
148+
throw new Exception( "$path already exists as a directory." );
149+
}
150+
151+
return;
152+
}
153+
154+
file_put_contents( $path, $contents );
155+
}
156+
157+
/**
158+
* Determines whether the operating system is Windows.
159+
*
160+
* @return bool Whether the operating system is Windows.
161+
*/
162+
public static function is_windows() {
163+
return 'WIN' === substr( PHP_OS, 0, 3 );
164+
}
165+
166+
/**
167+
* Data provider.
168+
*
169+
* @return array[]
170+
*/
171+
public function data_paths_that_exist() {
172+
return array(
173+
'a file that exists' => array(
174+
'path' => 'a_file_that_exists.txt',
175+
),
176+
'a directory that exists' => array(
177+
'path' => '',
178+
),
179+
);
180+
}
181+
182+
/**
183+
* Data provider.
184+
*
185+
* @return array[]
186+
*/
187+
public function data_paths_that_do_not_exist() {
188+
return array(
189+
'a file that does not exist' => array(
190+
'path' => 'a_file_that_does_not_exist.txt',
191+
),
192+
'a directory that does not exist' => array(
193+
'path' => 'a_directory_that_does_not_exist',
194+
),
195+
);
196+
}
197+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/**
3+
* Tests for the WP_Filesystem_Direct::chdir() method.
4+
*
5+
* @package WordPress
6+
*/
7+
8+
require_once __DIR__ . '/base.php';
9+
10+
/**
11+
* @group admin
12+
* @group filesystem
13+
* @group filesystem-direct
14+
*
15+
* @covers WP_Filesystem_Direct::chdir
16+
*/
17+
class Tests_Filesystem_WpFilesystemDirect_Chdir extends WP_Filesystem_Direct_UnitTestCase {
18+
19+
/**
20+
* Tests that `WP_Filesystem_Direct::chdir()`
21+
* returns false for a path that does not exist.
22+
*
23+
* @ticket 57774
24+
*
25+
* @dataProvider data_should_fail_to_change_directory
26+
*
27+
* @param string $path The path.
28+
*/
29+
public function test_should_fail_to_change_directory( $path ) {
30+
$original_cwd = self::$filesystem->cwd();
31+
$path = wp_normalize_path( realpath( self::$file_structure['test_dir']['path'] ) ) . $path;
32+
$chdir_result = self::$filesystem->chdir( $path );
33+
$cwd_result = self::$filesystem->cwd();
34+
35+
// Reset the current working directory.
36+
self::$filesystem->chdir( $original_cwd );
37+
38+
$this->assertFalse(
39+
$chdir_result,
40+
'Changing working directory succeeded.'
41+
);
42+
43+
$this->assertSame(
44+
$original_cwd,
45+
$cwd_result,
46+
'The current working directory was changed.'
47+
);
48+
}
49+
50+
/**
51+
* Data provider.
52+
*
53+
* @return array[]
54+
*/
55+
public function data_should_fail_to_change_directory() {
56+
return array(
57+
'a file that exists' => array(
58+
'path' => 'a_file_that_exists.txt',
59+
),
60+
'a file that does not exist' => array(
61+
'path' => 'a_file_that_does_not_exist.txt',
62+
),
63+
'a directory that does not exist' => array(
64+
'path' => 'a_directory_that_does_not_exist',
65+
),
66+
);
67+
}
68+
69+
/**
70+
* Tests that `WP_Filesystem_Direct::chdir()` changes to
71+
* an existing directory.
72+
*
73+
* @ticket 57774
74+
*/
75+
public function test_should_change_directory() {
76+
$original_cwd = self::$filesystem->cwd();
77+
$path = wp_normalize_path( realpath( self::$file_structure['test_dir']['path'] ) );
78+
$chdir_result = self::$filesystem->chdir( $path );
79+
$cwd_result = self::$filesystem->cwd();
80+
81+
// Reset the current working directory.
82+
self::$filesystem->chdir( $original_cwd );
83+
84+
$this->assertTrue(
85+
$chdir_result,
86+
'Changing working directory failed.'
87+
);
88+
89+
$this->assertSame(
90+
$path,
91+
$cwd_result,
92+
'The current working directory was incorrect.'
93+
);
94+
}
95+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Tests for the WP_Filesystem_Direct::chgrp() method.
4+
*
5+
* @package WordPress
6+
*/
7+
8+
require_once __DIR__ . '/base.php';
9+
10+
/**
11+
* @group admin
12+
* @group filesystem
13+
* @group filesystem-direct
14+
*
15+
* @covers WP_Filesystem_Direct::chgrp
16+
*/
17+
class Tests_Filesystem_WpFilesystemDirect_Chgrp extends WP_Filesystem_Direct_UnitTestCase {
18+
19+
/**
20+
* Tests that `WP_Filesystem_Direct::chgrp()`
21+
* returns false for a path that does not exist.
22+
*
23+
* @ticket 57774
24+
*
25+
* @dataProvider data_paths_that_do_not_exist
26+
*
27+
* @param string $path The path.
28+
*/
29+
public function test_should_fail_to_change_file_group( $path ) {
30+
$this->assertFalse( self::$filesystem->chgrp( self::$file_structure['test_dir']['path'] . $path, 0 ) );
31+
}
32+
}

0 commit comments

Comments
 (0)