FileSystemTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <?php
  2. namespace EasySwoole\Utility\Tests;
  3. use EasySwoole\Utility\FileSystem;
  4. use PHPUnit\Framework\Assert;
  5. use PHPUnit\Framework\TestCase;
  6. /**
  7. * Class FileSystemTest
  8. * @package EasySwoole\Utility\Tests
  9. * reference link https://github.com/laravel/framework/blob/8.x/tests/Filesystem/FilesystemTest.php
  10. */
  11. class FileSystemTest extends TestCase
  12. {
  13. protected static $tempDir;
  14. public static function setUpBeforeClass(): void
  15. {
  16. static::$tempDir = __DIR__ . '/Temp';
  17. $files = new FileSystem();
  18. $files->makeDirectory(static::$tempDir);
  19. }
  20. public static function tearDownAfterClass(): void
  21. {
  22. $files = new FileSystem();
  23. $files->deleteDirectory(static::$tempDir);
  24. }
  25. protected function tearDown(): void
  26. {
  27. $files = new FileSystem();
  28. $files->deleteDirectory(static::$tempDir, true);
  29. }
  30. public function testGet()
  31. {
  32. file_put_contents(self::$tempDir . '/file.txt', 'Hello World');
  33. $files = new Filesystem;
  34. $this->assertEquals('Hello World', $files->get(self::$tempDir . '/file.txt'));
  35. }
  36. public function testPut()
  37. {
  38. $files = new Filesystem;
  39. $files->put(self::$tempDir . '/file.txt', 'Hello World');
  40. $this->assertStringEqualsFile(self::$tempDir . '/file.txt', 'Hello World');
  41. }
  42. public function testReplace()
  43. {
  44. $tempFile = self::$tempDir . '/file.txt';
  45. $filesystem = new Filesystem;
  46. $filesystem->replace($tempFile, 'Hello World');
  47. $this->assertStringEqualsFile($tempFile, 'Hello World');
  48. }
  49. public function testSetChmod()
  50. {
  51. file_put_contents(self::$tempDir . '/file.txt', 'Hello World');
  52. $files = new Filesystem;
  53. $files->chmod(self::$tempDir . '/file.txt', 0755);
  54. $filePermission = substr(sprintf('%o', fileperms(self::$tempDir . '/file.txt')), -4);
  55. $expectedPermissions = DIRECTORY_SEPARATOR == '\\' ? '0666' : '0755';
  56. $this->assertEquals($expectedPermissions, $filePermission);
  57. }
  58. public function testGetChmod()
  59. {
  60. file_put_contents(self::$tempDir . '/file.txt', 'Hello World');
  61. chmod(self::$tempDir . '/file.txt', 0755);
  62. $files = new Filesystem;
  63. $filePermission = $files->chmod(self::$tempDir . '/file.txt');
  64. $expectedPermissions = DIRECTORY_SEPARATOR == '\\' ? '0666' : '0755';
  65. $this->assertEquals($expectedPermissions, $filePermission);
  66. }
  67. public function testDelete()
  68. {
  69. file_put_contents(self::$tempDir . '/file1.txt', 'Hello World');
  70. file_put_contents(self::$tempDir . '/file2.txt', 'Hello World');
  71. file_put_contents(self::$tempDir . '/file3.txt', 'Hello World');
  72. $files = new Filesystem;
  73. $files->delete(self::$tempDir . '/file1.txt');
  74. Assert::assertFileDoesNotExist(self::$tempDir . '/file1.txt');
  75. $files->delete([self::$tempDir . '/file2.txt', self::$tempDir . '/file3.txt']);
  76. Assert::assertFileDoesNotExist(self::$tempDir . '/file2.txt');
  77. Assert::assertFileDoesNotExist(self::$tempDir . '/file3.txt');
  78. }
  79. public function testPrependExistingFiles()
  80. {
  81. $files = new Filesystem;
  82. $files->put(self::$tempDir . '/file.txt', 'World');
  83. $files->prepend(self::$tempDir . '/file.txt', 'Hello ');
  84. $this->assertStringEqualsFile(self::$tempDir . '/file.txt', 'Hello World');
  85. }
  86. public function testPrependNewFiles()
  87. {
  88. $files = new Filesystem;
  89. $files->prepend(self::$tempDir . '/file.txt', 'Hello World');
  90. $this->assertStringEqualsFile(self::$tempDir . '/file.txt', 'Hello World');
  91. }
  92. public function testMissingFile()
  93. {
  94. $files = new Filesystem;
  95. $this->assertTrue($files->missing(self::$tempDir . '/file.txt'));
  96. }
  97. public function testDeleteDirectory()
  98. {
  99. mkdir(self::$tempDir . '/foo');
  100. file_put_contents(self::$tempDir . '/foo/file.txt', 'Hello World');
  101. $files = new Filesystem;
  102. $files->deleteDirectory(self::$tempDir . '/foo');
  103. Assert::assertDirectoryDoesNotExist(self::$tempDir . '/foo');
  104. Assert::assertFileDoesNotExist(self::$tempDir . '/foo/file.txt');
  105. }
  106. public function testDeleteDirectoryReturnFalseWhenNotADirectory()
  107. {
  108. mkdir(self::$tempDir . '/bar');
  109. file_put_contents(self::$tempDir . '/bar/file.txt', 'Hello World');
  110. $files = new Filesystem;
  111. $this->assertFalse($files->deleteDirectory(self::$tempDir . '/bar/file.txt'));
  112. }
  113. public function testCleanDirectory()
  114. {
  115. mkdir(self::$tempDir . '/baz');
  116. file_put_contents(self::$tempDir . '/baz/file.txt', 'Hello World');
  117. $files = new Filesystem;
  118. $files->cleanDirectory(self::$tempDir . '/baz');
  119. $this->assertDirectoryExists(self::$tempDir . '/baz');
  120. Assert::assertFileDoesNotExist(self::$tempDir . '/baz/file.txt');
  121. }
  122. public function testCopyDirectoryReturnsFalse()
  123. {
  124. $files = new Filesystem;
  125. $this->assertFalse($files->copyDirectory(self::$tempDir . '/breeze/boom/foo/bar/baz', self::$tempDir));
  126. }
  127. public function testCopyDirectoryMovesEntireDirectory()
  128. {
  129. mkdir(self::$tempDir . '/tmp', 0777, true);
  130. file_put_contents(self::$tempDir . '/tmp/foo.txt', '');
  131. file_put_contents(self::$tempDir . '/tmp/bar.txt', '');
  132. mkdir(self::$tempDir . '/tmp/nested', 0777, true);
  133. file_put_contents(self::$tempDir . '/tmp/nested/baz.txt', '');
  134. $files = new Filesystem;
  135. $files->copyDirectory(self::$tempDir . '/tmp', self::$tempDir . '/tmp2');
  136. $this->assertDirectoryExists(self::$tempDir . '/tmp2');
  137. $this->assertFileExists(self::$tempDir . '/tmp2/foo.txt');
  138. $this->assertFileExists(self::$tempDir . '/tmp2/bar.txt');
  139. $this->assertDirectoryExists(self::$tempDir . '/tmp2/nested');
  140. $this->assertFileExists(self::$tempDir . '/tmp2/nested/baz.txt');
  141. }
  142. public function testMoveDirectoryMovesEntireDirectory()
  143. {
  144. mkdir(self::$tempDir . '/tmp2', 0777, true);
  145. file_put_contents(self::$tempDir . '/tmp2/foo.txt', '');
  146. file_put_contents(self::$tempDir . '/tmp2/bar.txt', '');
  147. mkdir(self::$tempDir . '/tmp2/nested', 0777, true);
  148. file_put_contents(self::$tempDir . '/tmp2/nested/baz.txt', '');
  149. $files = new Filesystem;
  150. $files->moveDirectory(self::$tempDir . '/tmp2', self::$tempDir . '/tmp3');
  151. $this->assertDirectoryExists(self::$tempDir . '/tmp3');
  152. $this->assertFileExists(self::$tempDir . '/tmp3/foo.txt');
  153. $this->assertFileExists(self::$tempDir . '/tmp3/bar.txt');
  154. $this->assertDirectoryExists(self::$tempDir . '/tmp3/nested');
  155. $this->assertFileExists(self::$tempDir . '/tmp3/nested/baz.txt');
  156. Assert::assertDirectoryDoesNotExist(self::$tempDir . '/tmp2');
  157. }
  158. public function testMoveDirectoryMovesEntireDirectoryAndOverwrites()
  159. {
  160. mkdir(self::$tempDir . '/tmp4', 0777, true);
  161. file_put_contents(self::$tempDir . '/tmp4/foo.txt', '');
  162. file_put_contents(self::$tempDir . '/tmp4/bar.txt', '');
  163. mkdir(self::$tempDir . '/tmp4/nested', 0777, true);
  164. file_put_contents(self::$tempDir . '/tmp4/nested/baz.txt', '');
  165. mkdir(self::$tempDir . '/tmp5', 0777, true);
  166. file_put_contents(self::$tempDir . '/tmp5/foo2.txt', '');
  167. file_put_contents(self::$tempDir . '/tmp5/bar2.txt', '');
  168. $files = new Filesystem;
  169. $files->moveDirectory(self::$tempDir . '/tmp4', self::$tempDir . '/tmp5', true);
  170. $this->assertDirectoryExists(self::$tempDir . '/tmp5');
  171. $this->assertFileExists(self::$tempDir . '/tmp5/foo.txt');
  172. $this->assertFileExists(self::$tempDir . '/tmp5/bar.txt');
  173. $this->assertDirectoryExists(self::$tempDir . '/tmp5/nested');
  174. $this->assertFileExists(self::$tempDir . '/tmp5/nested/baz.txt');
  175. Assert::assertFileDoesNotExist(self::$tempDir . '/tmp5/foo2.txt');
  176. Assert::assertFileDoesNotExist(self::$tempDir . '/tmp5/bar2.txt');
  177. Assert::assertDirectoryDoesNotExist(self::$tempDir . '/tmp4');
  178. }
  179. public function testMoveDirectoryReturns()
  180. {
  181. mkdir(self::$tempDir . '/tmp6', 0777, true);
  182. file_put_contents(self::$tempDir . '/tmp6/foo.txt', '');
  183. mkdir(self::$tempDir . '/tmp7', 0777, true);
  184. $files = new FileSystem();
  185. $this->assertTrue($files->moveDirectory(self::$tempDir . '/tmp6', self::$tempDir . '/tmp7', true));
  186. }
  187. public function testGetThrowsException()
  188. {
  189. $this->expectException(\Exception::class);
  190. $files = new Filesystem;
  191. $files->get(self::$tempDir . '/unknown-file.txt');
  192. }
  193. public function testAppendAddsDataToFile()
  194. {
  195. file_put_contents(self::$tempDir . '/file.txt', 'foo');
  196. $files = new Filesystem;
  197. $bytesWritten = $files->append(self::$tempDir . '/file.txt', 'bar');
  198. $this->assertEquals(mb_strlen('bar', '8bit'), $bytesWritten);
  199. $this->assertFileExists(self::$tempDir . '/file.txt');
  200. $this->assertStringEqualsFile(self::$tempDir . '/file.txt', 'foobar');
  201. }
  202. public function testMoveMovesFiles()
  203. {
  204. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  205. $files = new Filesystem;
  206. $files->move(self::$tempDir . '/foo.txt', self::$tempDir . '/bar.txt');
  207. $this->assertFileExists(self::$tempDir . '/bar.txt');
  208. Assert::assertFileDoesNotExist(self::$tempDir . '/foo.txt');
  209. }
  210. public function testNameReturnsName()
  211. {
  212. file_put_contents(self::$tempDir . '/foobar.txt', 'foo');
  213. $filesystem = new Filesystem;
  214. $this->assertSame('foobar', $filesystem->name(self::$tempDir . '/foobar.txt'));
  215. }
  216. public function testExtensionReturnsExtension()
  217. {
  218. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  219. $files = new Filesystem;
  220. $this->assertSame('txt', $files->extension(self::$tempDir . '/foo.txt'));
  221. }
  222. public function testBasenameReturnsBasename()
  223. {
  224. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  225. $files = new Filesystem;
  226. $this->assertSame('foo.txt', $files->basename(self::$tempDir . '/foo.txt'));
  227. }
  228. public function testDirnameReturnsDirectory()
  229. {
  230. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  231. $files = new Filesystem;
  232. $this->assertEquals(self::$tempDir, $files->dirname(self::$tempDir . '/foo.txt'));
  233. }
  234. public function testTypeIdentifiesFile()
  235. {
  236. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  237. $files = new Filesystem;
  238. $this->assertSame('file', $files->type(self::$tempDir . '/foo.txt'));
  239. }
  240. public function testTypeIdentifiesDirectory()
  241. {
  242. mkdir(self::$tempDir . '/foo-dir');
  243. $files = new Filesystem;
  244. $this->assertSame('dir', $files->type(self::$tempDir . '/foo-dir'));
  245. }
  246. public function testSizeOutputsSize()
  247. {
  248. $size = file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  249. $files = new Filesystem;
  250. $this->assertEquals($size, $files->size(self::$tempDir . '/foo.txt'));
  251. }
  252. public function testIsWritable()
  253. {
  254. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  255. $files = new Filesystem;
  256. @chmod(self::$tempDir . '/foo.txt', 0444);
  257. $this->assertFalse($files->isWritable(self::$tempDir . '/foo.txt'));
  258. @chmod(self::$tempDir . '/foo.txt', 0777);
  259. $this->assertTrue($files->isWritable(self::$tempDir . '/foo.txt'));
  260. }
  261. public function testIsReadable()
  262. {
  263. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  264. $files = new Filesystem;
  265. // chmod is noneffective on Windows
  266. if (DIRECTORY_SEPARATOR === '\\') {
  267. $this->assertTrue($files->isReadable(self::$tempDir . '/foo.txt'));
  268. } else {
  269. @chmod(self::$tempDir . '/foo.txt', 0000);
  270. $this->assertFalse($files->isReadable(self::$tempDir . '/foo.txt'));
  271. @chmod(self::$tempDir . '/foo.txt', 0777);
  272. $this->assertTrue($files->isReadable(self::$tempDir . '/foo.txt'));
  273. }
  274. $this->assertFalse($files->isReadable(self::$tempDir . '/doesnotexist.txt'));
  275. }
  276. public function testGlobFindsFiles()
  277. {
  278. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  279. file_put_contents(self::$tempDir . '/bar.txt', 'bar');
  280. $files = new Filesystem;
  281. $glob = $files->glob(self::$tempDir . '/*.txt');
  282. $this->assertContains(self::$tempDir . '/foo.txt', $glob);
  283. $this->assertContains(self::$tempDir . '/bar.txt', $glob);
  284. }
  285. public function testMakeDirectory()
  286. {
  287. $files = new Filesystem;
  288. $this->assertTrue($files->makeDirectory(self::$tempDir . '/created'));
  289. $this->assertFileExists(self::$tempDir . '/created');
  290. }
  291. /**
  292. * @requires extension pcntl
  293. * @requires function pcntl_fork
  294. */
  295. public function testSharedGet()
  296. {
  297. if (PHP_OS == 'Darwin') {
  298. $this->markTestSkipped('The operating system is MacOS.');
  299. }
  300. $content = str_repeat('123456', 1000000);
  301. $result = 1;
  302. posix_setpgid(0, 0);
  303. for ($i = 1; $i <= 20; $i++) {
  304. $pid = pcntl_fork();
  305. if (!$pid) {
  306. $files = new Filesystem;
  307. $files->put(self::$tempDir . '/file.txt', $content, true);
  308. $read = $files->get(self::$tempDir . '/file.txt', true);
  309. exit(strlen($read) === strlen($content) ? 1 : 0);
  310. }
  311. }
  312. while (pcntl_waitpid(0, $status) != -1) {
  313. $status = pcntl_wexitstatus($status);
  314. $result *= $status;
  315. }
  316. $this->assertSame(1, $result);
  317. }
  318. public function testCopyCopiesFileProperly()
  319. {
  320. $filesystem = new Filesystem;
  321. $data = 'contents';
  322. mkdir(self::$tempDir . '/text');
  323. file_put_contents(self::$tempDir . '/text/foo.txt', $data);
  324. $filesystem->copy(self::$tempDir . '/text/foo.txt', self::$tempDir . '/text/foo2.txt');
  325. $this->assertFileExists(self::$tempDir . '/text/foo2.txt');
  326. $this->assertEquals($data, file_get_contents(self::$tempDir . '/text/foo2.txt'));
  327. }
  328. public function testIsFileChecksFilesProperly()
  329. {
  330. $filesystem = new Filesystem;
  331. mkdir(self::$tempDir . '/help');
  332. file_put_contents(self::$tempDir . '/help/foo.txt', 'contents');
  333. $this->assertTrue($filesystem->isFile(self::$tempDir . '/help/foo.txt'));
  334. $this->assertFalse($filesystem->isFile(self::$tempDir . './help'));
  335. }
  336. public function testHash()
  337. {
  338. file_put_contents(self::$tempDir . '/foo.txt', 'foo');
  339. $filesystem = new Filesystem;
  340. $this->assertSame('acbd18db4cc2f85cedef654fccc4a4d8', $filesystem->hash(self::$tempDir . '/foo.txt'));
  341. }
  342. }