From 923effe11d3de1d60fc006d9927177a7b0f5b6eb Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 10 Sep 2015 16:39:32 +0300 Subject: [PATCH] Change FilePathComponents parsing for file with empty name to enhance finding relative path between relative paths. --- .../src/kotlin/io/files/FilePathComponents.kt | 4 +- libraries/stdlib/test/io/Files.kt | 46 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt b/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt index c1344b482ec..4d72925be48 100644 --- a/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt +++ b/libraries/stdlib/src/kotlin/io/files/FilePathComponents.kt @@ -113,9 +113,9 @@ public fun File.filePathComponents(): FilePathComponents { val subPath = path.substring(rootName.length) // if: a special case when we have only root component // Split not only by / or \, but also by //, ///, \\, \\\, etc. - val list = if (rootName.length > 0 && subPath.isEmpty()) listOf() else + val list = if (subPath.isEmpty()) listOf() else // Looks awful but we split just by /+ or \+ depending on OS - subPath.split(Regex.fromLiteral(File.separatorChar.toString())).toList().map { it -> File(it) } + subPath.split(Regex.fromLiteral(File.separatorChar.toString())).map { it -> File(it) } return FilePathComponents(rootName, list) } diff --git a/libraries/stdlib/test/io/Files.kt b/libraries/stdlib/test/io/Files.kt index b812170b782..8301da9a0b4 100644 --- a/libraries/stdlib/test/io/Files.kt +++ b/libraries/stdlib/test/io/Files.kt @@ -69,35 +69,69 @@ class FilesTest { assertEquals(2, result2!!.size) } - @test fun relativeToTest() { + @test fun relativeToRooted() { val file1 = File("/foo/bar/baz") val file2 = File("/foo/baa/ghoo") + assertEquals("../../bar/baz".separatorsToSystem(), file1.relativeTo(file2)) + val file3 = File("/foo/bar") + assertEquals("baz", file1.relativeTo(file3)) assertEquals("..", file3.relativeTo(file1)) + val file4 = File("/foo/bar/") + assertEquals("baz", file1.relativeTo(file4)) assertEquals("..", file4.relativeTo(file1)) assertEquals("", file3.relativeTo(file4)) assertEquals("", file4.relativeTo(file3)) + val file5 = File("/foo/baran") + assertEquals("../bar".separatorsToSystem(), file3.relativeTo(file5)) assertEquals("../baran".separatorsToSystem(), file5.relativeTo(file3)) assertEquals("../bar".separatorsToSystem(), file4.relativeTo(file5)) assertEquals("../baran".separatorsToSystem(), file5.relativeTo(file4)) + val file6 = File("C:\\Users\\Me") val file7 = File("C:\\Users\\Me\\Documents") + assertEquals("..", file6.relativeTo(file7)) assertEquals("Documents", file7.relativeTo(file6)) + val file8 = File("""\\my.host\home/user/documents/vip""") val file9 = File("""\\my.host\home/other/images/nice""") + assertEquals("../../../user/documents/vip".separatorsToSystem(), file8.relativeTo(file9)) assertEquals("../../../other/images/nice".separatorsToSystem(), file9.relativeTo(file8)) - val file10 = File("foo/bar") - val file11 = File("foo") - assertEquals("bar", file10.relativeTo(file11)) - assertEquals("..", file11.relativeTo(file10)) + } + + @test fun relativeToRelative() { + val nested = File("foo/bar") + val base = File("foo") + + assertEquals("bar", nested.relativeTo(base)) + assertEquals("..", base.relativeTo(nested)) + assertEquals("", base.relativeTo(base)) + assertEquals("", nested.relativeTo(nested)) + + val empty = File("") + val current = File(".") + val parent = File("..") + val outOfRoot = File("../bar") + + assertEquals("../bar".separatorsToSystem(), outOfRoot.relativeTo(empty)) + + val root = File("/root") + val files = listOf(nested, base, empty, outOfRoot, current, parent) + for (file1 in files) { + for (file2 in files) { + val rootedFile1 = root.resolve(file1) + val rootedFile2 = root.resolve(file2) + assertEquals(file1.relativeTo(file2), rootedFile1.relativeTo(rootedFile2), "nested: $file1, base: $file2") + } + } } @test fun relativeToFails() { @@ -161,7 +195,7 @@ class FilesTest { checkFileElements(File("\\\\host.ru\\home\\mike"), File("\\\\host.ru\\home"), listOf("mike")) checkFileElements(File("//host.ru/home/mike"), File("//host.ru/home"), listOf("mike")) } - checkFileElements(File(""), null, listOf("")) + checkFileElements(File(""), null, listOf()) checkFileElements(File("."), null, listOf(".")) checkFileElements(File(".."), null, listOf("..")) }