+ 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));
+ }
+