$this->assertSame($owner, $this->getFileOwner($link));
}
+ public function testChownLink()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $owner = $this->getFileOwner($link);
+ $this->filesystem->chown($link, $owner);
+
+ $this->assertSame($owner, $this->getFileOwner($link));
+ }
+
/**
* @expectedException \Symfony\Component\Filesystem\Exception\IOException
*/
$this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
}
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChownLinkFails()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999));
+ }
+
/**
* @expectedException \Symfony\Component\Filesystem\Exception\IOException
*/
$this->assertSame($group, $this->getFileGroup($link));
}
+ public function testChgrpLink()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $group = $this->getFileGroup($link);
+ $this->filesystem->chgrp($link, $group);
+
+ $this->assertSame($group, $this->getFileGroup($link));
+ }
+
/**
* @expectedException \Symfony\Component\Filesystem\Exception\IOException
*/
$this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
}
+ /**
+ * @expectedException \Symfony\Component\Filesystem\Exception\IOException
+ */
+ public function testChgrpLinkFails()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999));
+ }
+
/**
* @expectedException \Symfony\Component\Filesystem\Exception\IOException
*/
$this->assertEquals($file, readlink($link2));
}
+ public function testLink()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+ $this->filesystem->hardlink($file, $link);
+
+ $this->assertTrue(is_file($link));
+ $this->assertEquals(fileinode($file), fileinode($link));
+ }
+
+ /**
+ * @depends testLink
+ */
+ public function testRemoveLink()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ $this->filesystem->remove($link);
+
+ $this->assertTrue(!is_file($link));
+ }
+
+ public function testLinkIsOverwrittenIfPointsToDifferentTarget()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $file2 = $this->workspace.DIRECTORY_SEPARATOR.'file2';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+ touch($file2);
+ link($file2, $link);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $this->assertTrue(is_file($link));
+ $this->assertEquals(fileinode($file), fileinode($link));
+ }
+
+ public function testLinkIsNotOverwrittenIfAlreadyCreated()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+ link($file, $link);
+
+ $this->filesystem->hardlink($file, $link);
+
+ $this->assertTrue(is_file($link));
+ $this->assertEquals(fileinode($file), fileinode($link));
+ }
+
+ public function testLinkWithSeveralTargets()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link1 = $this->workspace.DIRECTORY_SEPARATOR.'link';
+ $link2 = $this->workspace.DIRECTORY_SEPARATOR.'link2';
+
+ touch($file);
+
+ $this->filesystem->hardlink($file, array($link1, $link2));
+
+ $this->assertTrue(is_file($link1));
+ $this->assertEquals(fileinode($file), fileinode($link1));
+ $this->assertTrue(is_file($link2));
+ $this->assertEquals(fileinode($file), fileinode($link2));
+ }
+
+ public function testLinkWithSameTarget()
+ {
+ $this->markAsSkippedIfLinkIsMissing();
+
+ $file = $this->workspace.DIRECTORY_SEPARATOR.'file';
+ $link = $this->workspace.DIRECTORY_SEPARATOR.'link';
+
+ touch($file);
+
+ // practically same as testLinkIsNotOverwrittenIfAlreadyCreated
+ $this->filesystem->hardlink($file, array($link, $link));
+
+ $this->assertTrue(is_file($link));
+ $this->assertEquals(fileinode($file), fileinode($link));
+ }
+
+ public function testReadRelativeLink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Relative symbolic links are not supported on Windows');
+ }
+
+ $file = $this->workspace.'/file';
+ $link1 = $this->workspace.'/dir/link';
+ $link2 = $this->workspace.'/dir/link2';
+ touch($file);
+
+ $this->filesystem->symlink('../file', $link1);
+ $this->filesystem->symlink('link', $link2);
+
+ $this->assertEquals($this->normalize('../file'), $this->filesystem->readlink($link1));
+ $this->assertEquals('link', $this->filesystem->readlink($link2));
+ $this->assertEquals($file, $this->filesystem->readlink($link1, true));
+ $this->assertEquals($file, $this->filesystem->readlink($link2, true));
+ $this->assertEquals($file, $this->filesystem->readlink($file, true));
+ }
+
+ public function testReadAbsoluteLink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->normalize($this->workspace.'/file');
+ $link1 = $this->normalize($this->workspace.'/dir/link');
+ $link2 = $this->normalize($this->workspace.'/dir/link2');
+ touch($file);
+
+ $this->filesystem->symlink($file, $link1);
+ $this->filesystem->symlink($link1, $link2);
+
+ $this->assertEquals($file, $this->filesystem->readlink($link1));
+ $this->assertEquals($link1, $this->filesystem->readlink($link2));
+ $this->assertEquals($file, $this->filesystem->readlink($link1, true));
+ $this->assertEquals($file, $this->filesystem->readlink($link2, true));
+ $this->assertEquals($file, $this->filesystem->readlink($file, true));
+ }
+
+ public function testReadBrokenLink()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('Windows does not support creating "broken" symlinks');
+ }
+
+ $file = $this->workspace.'/file';
+ $link = $this->workspace.'/link';
+
+ $this->filesystem->symlink($file, $link);
+
+ $this->assertEquals($file, $this->filesystem->readlink($link));
+ $this->assertNull($this->filesystem->readlink($link, true));
+
+ touch($file);
+ $this->assertEquals($file, $this->filesystem->readlink($link, true));
+ }
+
+ public function testReadLinkDefaultPathDoesNotExist()
+ {
+ $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'/invalid')));
+ }
+
+ public function testReadLinkDefaultPathNotLink()
+ {
+ $file = $this->normalize($this->workspace.'/file');
+ touch($file);
+
+ $this->assertNull($this->filesystem->readlink($file));
+ }
+
+ public function testReadLinkCanonicalizePath()
+ {
+ $this->markAsSkippedIfSymlinkIsMissing();
+
+ $file = $this->normalize($this->workspace.'/file');
+ mkdir($this->normalize($this->workspace.'/dir'));
+ touch($file);
+
+ $this->assertEquals($file, $this->filesystem->readlink($this->normalize($this->workspace.'/dir/../file'), true));
+ }
+
+ public function testReadLinkCanonicalizedPathDoesNotExist()
+ {
+ $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'invalid'), true));
+ }
+
/**
* @dataProvider providePathsForMakePathRelative
*/
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'),
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'),
array('/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'),
- array('var/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../'),
array('/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
- array('usr/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
array('/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'),
array('/aa/bb', '/aa/bb', './'),
array('/aa/bb', '/aa/bb/', './'),
array('C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'),
array('C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'),
array('C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'),
+ );
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
+ }
+
+ return $paths;
+ }
+
+ /**
+ * @group legacy
+ * @dataProvider provideLegacyPathsForMakePathRelativeWithRelativePaths
+ * @expectedDeprecation Support for passing relative paths to Symfony\Component\Filesystem\Filesystem::makePathRelative() is deprecated since Symfony 3.4 and will be removed in 4.0.
+ */
+ public function testMakePathRelativeWithRelativePaths($endPath, $startPath, $expectedPath)
+ {
+ $path = $this->filesystem->makePathRelative($endPath, $startPath);
+
+ $this->assertEquals($expectedPath, $path);
+ }
+
+ public function provideLegacyPathsForMakePathRelativeWithRelativePaths()
+ {
+ return array(
+ array('usr/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'),
array('aa/bb', 'aa/cc', '../bb/'),
array('aa/cc', 'bb/cc', '../../aa/cc/'),
array('aa/bb', 'aa/./cc', '../bb/'),
array('', 'aa/', '../'),
array('aa/', '', 'aa/'),
);
-
- if ('\\' === DIRECTORY_SEPARATOR) {
- $paths[] = array('c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/');
- }
-
- return $paths;
}
public function testMirrorCopiesFilesAndDirectoriesRecursively()
{
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
- $this->filesystem->dumpFile($filename, 'bar');
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $oldMask = umask(0002);
+ }
+ $this->filesystem->dumpFile($filename, 'bar');
$this->assertFileExists($filename);
$this->assertStringEqualsFile($filename, 'bar');
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->assertFilePermissions(664, $filename);
+ umask($oldMask);
+ }
}
- /**
- * @group legacy
- */
- public function testDumpFileAndSetPermissions()
+ public function testDumpFileOverwritesAnExistingFile()
{
- $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
+ file_put_contents($filename, 'FOO BAR');
- $this->filesystem->dumpFile($filename, 'bar', 0753);
+ $this->filesystem->dumpFile($filename, 'bar');
$this->assertFileExists($filename);
$this->assertStringEqualsFile($filename, 'bar');
+ }
- // skip mode check on Windows
- if ('\\' !== DIRECTORY_SEPARATOR) {
- $this->assertFilePermissions(753, $filename);
+ public function testDumpFileWithFileScheme()
+ {
+ if (defined('HHVM_VERSION')) {
+ $this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
}
+
+ $scheme = 'file://';
+ $filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+
+ $this->filesystem->dumpFile($filename, 'bar');
+
+ $this->assertFileExists($filename);
+ $this->assertStringEqualsFile($filename, 'bar');
}
- public function testDumpFileWithNullMode()
+ public function testDumpFileWithZlibScheme()
{
+ $scheme = 'compress.zlib://';
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
- $this->filesystem->dumpFile($filename, 'bar', null);
+ $this->filesystem->dumpFile($filename, 'bar');
- $this->assertFileExists($filename);
+ // Zlib stat uses file:// wrapper so remove scheme
+ $this->assertFileExists(str_replace($scheme, '', $filename));
$this->assertStringEqualsFile($filename, 'bar');
+ }
+
+ public function testAppendToFile()
+ {
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';
// skip mode check on Windows
if ('\\' !== DIRECTORY_SEPARATOR) {
- $this->assertFilePermissions(600, $filename);
+ $oldMask = umask(0002);
}
- }
- public function testDumpFileOverwritesAnExistingFile()
- {
- $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo.txt';
- file_put_contents($filename, 'FOO BAR');
+ $this->filesystem->dumpFile($filename, 'foo');
- $this->filesystem->dumpFile($filename, 'bar');
+ $this->filesystem->appendToFile($filename, 'bar');
$this->assertFileExists($filename);
- $this->assertStringEqualsFile($filename, 'bar');
+ $this->assertStringEqualsFile($filename, 'foobar');
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->assertFilePermissions(664, $filename);
+ umask($oldMask);
+ }
}
- public function testDumpFileWithFileScheme()
+ public function testAppendToFileWithScheme()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
$scheme = 'file://';
$filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+ $this->filesystem->dumpFile($filename, 'foo');
- $this->filesystem->dumpFile($filename, 'bar', null);
+ $this->filesystem->appendToFile($filename, 'bar');
$this->assertFileExists($filename);
- $this->assertSame('bar', file_get_contents($filename));
+ $this->assertStringEqualsFile($filename, 'foobar');
}
- public function testDumpFileWithZlibScheme()
+ public function testAppendToFileWithZlibScheme()
{
$scheme = 'compress.zlib://';
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
+ $this->filesystem->dumpFile($filename, 'foo');
- $this->filesystem->dumpFile($filename, 'bar', null);
+ // Zlib stat uses file:// wrapper so remove it
+ $this->assertStringEqualsFile(str_replace($scheme, '', $filename), 'foo');
- // Zlib stat uses file:// wrapper so remove scheme
- $this->assertFileExists(str_replace($scheme, '', $filename));
- $this->assertSame('bar', file_get_contents($filename));
+ $this->filesystem->appendToFile($filename, 'bar');
+
+ $this->assertFileExists($filename);
+ $this->assertStringEqualsFile($filename, 'foobar');
+ }
+
+ public function testAppendToFileCreateTheFileIfNotExists()
+ {
+ $filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $oldMask = umask(0002);
+ }
+
+ $this->filesystem->appendToFile($filename, 'bar');
+
+ // skip mode check on Windows
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $this->assertFilePermissions(664, $filename);
+ umask($oldMask);
+ }
+
+ $this->assertFileExists($filename);
+ $this->assertStringEqualsFile($filename, 'bar');
}
public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile()
$this->assertFilePermissions(767, $targetFilePath);
}
+
+ /**
+ * Normalize the given path (transform each blackslash into a real directory separator).
+ *
+ * @param string $path
+ *
+ * @return string
+ */
+ private function normalize($path)
+ {
+ return str_replace('/', DIRECTORY_SEPARATOR, $path);
+ }
}