1
0
mirror of https://github.com/danog/file.git synced 2024-11-30 04:19:39 +01:00
file/test/DriverTest.php

433 lines
12 KiB
PHP
Raw Normal View History

<?php
2015-07-11 03:59:39 +02:00
2015-08-05 16:55:56 +02:00
namespace Amp\File\Test;
2015-07-11 03:59:39 +02:00
2015-08-08 16:09:07 +02:00
use Amp\File as file;
2017-05-18 05:58:39 +02:00
use Amp\PHPUnit\TestCase;
2015-07-11 03:59:39 +02:00
abstract class DriverTest extends TestCase
{
protected function setUp()
{
Fixture::init();
File\StatCache::clear();
2015-07-19 16:38:40 +02:00
}
protected function tearDown()
{
Fixture::clear();
2015-08-08 16:09:07 +02:00
}
2017-01-11 14:22:06 +01:00
abstract protected function execute(callable $cb);
2015-08-08 16:09:07 +02:00
public function testScandir()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2017-06-17 15:36:51 +02:00
$actual = yield File\scandir($fixtureDir);
2015-07-11 03:59:39 +02:00
$expected = ["dir", "small.txt"];
$this->assertSame($expected, $actual);
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
2015-08-08 16:09:07 +02:00
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testScandirThrowsIfPathNotADirectory()
{
$this->execute(function () {
(yield File\scandir(__FILE__));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testScandirThrowsIfPathDoesntExist()
{
$this->execute(function () {
$path = Fixture::path() . "/nonexistent";
(yield File\scandir($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testSymlink()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-11 03:59:39 +02:00
2015-08-08 16:09:07 +02:00
$original = "{$fixtureDir}/small.txt";
2015-07-19 16:38:40 +02:00
$link = "{$fixtureDir}/symlink.txt";
$this->assertTrue(yield File\symlink($original, $link));
$this->assertTrue(\is_link($link));
yield File\unlink($link);
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
public function testReadlink()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
$original = "{$fixtureDir}/small.txt";
$link = "{$fixtureDir}/symlink.txt";
\symlink($original, $link);
$this->assertSame($original, yield File\readlink($link));
});
}
public function readlinkPathProvider()
{
return [
'nonExistingPath' => [function () {
return Fixture::path() . '/' . \uniqid();
}],
'notLink' => [function () {
return Fixture::path();
}],
];
}
/**
* @dataProvider readlinkPathProvider
* @expectedException \Amp\File\FilesystemException
*
* @param \Closure $linkResolver
*/
public function testReadlinkError(\Closure $linkResolver)
{
$this->execute(function () use ($linkResolver) {
$link = $linkResolver();
yield File\readlink($link);
});
}
public function testLstat()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-11 03:59:39 +02:00
2015-07-19 16:38:40 +02:00
$target = "{$fixtureDir}/small.txt";
$link = "{$fixtureDir}/symlink.txt";
$this->assertTrue(yield File\symlink($target, $link));
2017-06-17 23:41:57 +02:00
$this->assertInternalType('array', yield File\lstat($link));
yield File\unlink($link);
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
public function testFileStat()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
$stat = (yield File\stat("{$fixtureDir}/small.txt"));
2015-08-08 16:09:07 +02:00
$this->assertInternalType("array", $stat);
2018-07-18 07:00:53 +02:00
$this->assertStatSame(\stat("{$fixtureDir}/small.txt"), $stat);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
2015-07-11 03:59:39 +02:00
public function testDirStat()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
$stat = (yield File\stat("{$fixtureDir}/dir"));
2015-07-19 15:24:52 +02:00
$this->assertInternalType("array", $stat);
2018-07-18 07:00:53 +02:00
$this->assertStatSame(\stat("{$fixtureDir}/dir"), $stat);
2015-08-08 17:46:34 +02:00
});
2015-07-19 15:24:52 +02:00
}
public function testNonexistentPathStatResolvesToNull()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
$stat = (yield File\stat("{$fixtureDir}/nonexistent"));
2015-08-08 16:09:07 +02:00
$this->assertNull($stat);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
2015-07-11 03:59:39 +02:00
public function testExists()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
$this->assertFalse(yield File\exists("{$fixtureDir}/nonexistent"));
$this->assertTrue(yield File\exists("{$fixtureDir}/small.txt"));
2015-08-08 17:46:34 +02:00
});
2015-07-19 15:24:52 +02:00
}
public function testGet()
{
2017-06-17 15:36:51 +02:00
$this->execute(function () {
$fixtureDir = Fixture::path();
$this->assertSame("small", yield File\get("{$fixtureDir}/small.txt"));
});
}
public function testSize()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$stat = (yield File\stat($path));
2015-08-08 16:09:07 +02:00
$size = $stat["size"];
File\StatCache::clear($path);
$this->assertSame($size, (yield File\size($path)));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
2015-07-11 03:59:39 +02:00
2015-08-08 16:09:07 +02:00
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testSizeFailsOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
yield File\size($path);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testSizeFailsOnDirectoryPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/dir";
$this->assertTrue(yield File\isdir($path));
File\StatCache::clear($path);
yield File\size($path);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsdirResolvesTrueOnDirectoryPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/dir";
$this->assertTrue(yield File\isdir($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsdirResolvesFalseOnFilePath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$this->assertFalse(yield File\isdir($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsdirResolvesFalseOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
$this->assertFalse(yield File\isdir($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsfileResolvesTrueOnFilePath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$this->assertTrue(yield File\isfile($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsfileResolvesFalseOnDirectoryPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/dir";
$this->assertFalse(yield File\isfile($path));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testIsfileResolvesFalseOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
$this->assertFalse(yield File\isfile($path));
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
public function testRename()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-11 03:59:39 +02:00
$contents1 = "rename test";
2015-07-19 16:38:40 +02:00
$old = "{$fixtureDir}/rename1.txt";
$new = "{$fixtureDir}/rename2.txt";
2015-07-11 03:59:39 +02:00
yield File\put($old, $contents1);
yield File\rename($old, $new);
$contents2 = (yield File\get($new));
yield File\unlink($new);
2015-07-11 03:59:39 +02:00
$this->assertSame($contents1, $contents2);
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
public function testUnlink()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-19 16:38:40 +02:00
$toUnlink = "{$fixtureDir}/unlink";
yield File\put($toUnlink, "unlink me");
yield File\unlink($toUnlink);
$this->assertNull(yield File\stat($toUnlink));
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
public function testMkdirRmdir()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-11 03:59:39 +02:00
2015-07-19 16:38:40 +02:00
$dir = "{$fixtureDir}/newdir";
2015-07-11 03:59:39 +02:00
2018-03-15 18:35:10 +01:00
\umask(0022);
yield File\mkdir($dir);
$stat = yield File\stat($dir);
2018-03-15 18:35:10 +01:00
$this->assertSame('0755', $this->getPermissionsFromStat($stat));
yield File\rmdir($dir);
$this->assertNull(yield File\stat($dir));
2016-09-28 12:39:24 +02:00
// test for 0, because previous array_filter made that not work
$dir = "{$fixtureDir}/newdir/with/recursive/creation/0/1/2";
2016-09-28 12:39:24 +02:00
yield File\mkdir($dir, 0764, true);
$stat = yield File\stat($dir);
2018-03-15 18:35:10 +01:00
$this->assertSame('0744', $this->getPermissionsFromStat($stat));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testMtime()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$stat = (yield File\stat($path));
2015-08-08 16:09:07 +02:00
$statMtime = $stat["mtime"];
File\StatCache::clear($path);
$this->assertSame($statMtime, (yield File\mtime($path)));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testMtimeFailsOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
yield File\mtime($path);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testAtime()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$stat = (yield File\stat($path));
2015-08-08 16:09:07 +02:00
$statAtime = $stat["atime"];
File\StatCache::clear($path);
$this->assertSame($statAtime, (yield File\atime($path)));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testAtimeFailsOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
yield File\atime($path);
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
public function testCtime()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/small.txt";
$stat = (yield File\stat($path));
2015-08-08 16:09:07 +02:00
$statCtime = $stat["ctime"];
File\StatCache::clear($path);
$this->assertSame($statCtime, (yield File\ctime($path)));
2015-08-08 17:46:34 +02:00
});
2015-08-08 16:09:07 +02:00
}
/**
* @expectedException \Amp\File\FilesystemException
*/
public function testCtimeFailsOnNonexistentPath()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-08-08 16:09:07 +02:00
$path = "{$fixtureDir}/nonexistent";
yield File\ctime($path);
2015-08-08 17:46:34 +02:00
});
2015-07-11 03:59:39 +02:00
}
2015-07-18 20:53:46 +02:00
/**
* @group slow
*/
public function testTouch()
{
$this->execute(function () {
$fixtureDir = Fixture::path();
2015-07-18 20:53:46 +02:00
2015-07-19 16:38:40 +02:00
$touch = "{$fixtureDir}/touch";
yield File\put($touch, "touch me");
2015-07-18 20:53:46 +02:00
$oldStat = (yield File\stat($touch));
yield File\touch($touch, \time() + 10, \time() + 20);
File\StatCache::clear($touch);
$newStat = (yield File\stat($touch));
yield File\unlink($touch);
2015-07-18 20:53:46 +02:00
$this->assertTrue($newStat["atime"] > $oldStat["atime"]);
$this->assertTrue($newStat["mtime"] > $oldStat["mtime"]);
2015-08-08 17:46:34 +02:00
});
2015-07-18 20:53:46 +02:00
}
2018-03-15 18:35:10 +01:00
private function assertStatSame(array $expected, array $actual)
{
2018-07-18 07:00:53 +02:00
$filter = function (array $stat) {
$filtered = \array_filter(
$stat,
function (string $key): bool {
return !\is_numeric($key);
},
ARRAY_FILTER_USE_KEY
);
\ksort($filtered);
2018-07-18 07:00:53 +02:00
return $filtered;
};
$this->assertSame($filter($expected), $filter($actual));
}
2018-03-15 18:35:10 +01:00
/**
* @param array $stat
* @return string
*/
private function getPermissionsFromStat(array $stat): string
{
2018-03-15 18:35:10 +01:00
return \substr(\decoct($stat["mode"]), 1);
}
2015-07-11 03:59:39 +02:00
}