Sensible behavior for File.startsWith and File.endsWith

This commit is contained in:
Ilya Gorbunov
2015-12-10 07:06:54 +03:00
parent d2e22dc794
commit a4f82a2dc4
2 changed files with 19 additions and 14 deletions
@@ -379,14 +379,13 @@ public fun File.listFiles(filter: (file: File) -> Boolean): Array<File>? = listF
* Determines whether this file belongs to the same root as [other] * Determines whether this file belongs to the same root as [other]
* and starts with all components of [other] in the same order. * and starts with all components of [other] in the same order.
* So if [other] has N components, first N components of `this` must be the same as in [other]. * So if [other] has N components, first N components of `this` must be the same as in [other].
* For relative [other], `this` can belong to any root.
* *
* @return `true` if this path starts with [other] path, `false` otherwise. * @return `true` if this path starts with [other] path, `false` otherwise.
*/ */
public fun File.startsWith(other: File): Boolean { public fun File.startsWith(other: File): Boolean {
val components = toComponents() val components = toComponents()
val otherComponents = other.toComponents() val otherComponents = other.toComponents()
if (components.root != otherComponents.root && otherComponents.rootName != "") if (components.root != otherComponents.root)
return false return false
return if (components.size < otherComponents.size) false return if (components.size < otherComponents.size) false
else components.segments.subList(0, otherComponents.size).equals(otherComponents.segments) else components.segments.subList(0, otherComponents.size).equals(otherComponents.segments)
@@ -396,25 +395,25 @@ public fun File.startsWith(other: File): Boolean {
* Determines whether this file belongs to the same root as [other] * Determines whether this file belongs to the same root as [other]
* and starts with all components of [other] in the same order. * and starts with all components of [other] in the same order.
* So if [other] has N components, first N components of `this` must be the same as in [other]. * So if [other] has N components, first N components of `this` must be the same as in [other].
* For relative [other], `this` can belong to any root.
* *
* @return `true` if this path starts with [other] path, `false` otherwise. * @return `true` if this path starts with [other] path, `false` otherwise.
*/ */
public fun File.startsWith(other: String): Boolean = startsWith(File(other)) public fun File.startsWith(other: String): Boolean = startsWith(File(other))
/** /**
* Determines whether this file belongs to the same root as [other] * Determines whether this file path ends with the path of [other] file.
* and ends with all components of [other] in the same order. *
* So if [other] has N components, last N components of `this` must be the same as in [other]. * If [other] is rooted path it must be equal to this.
* For relative [other], `this` can belong to any root. * If [other] is relative path then last N components of `this` must be the same as all components in [other],
* where N is the number of components in [other].
* *
* @return `true` if this path ends with [other] path, `false` otherwise. * @return `true` if this path ends with [other] path, `false` otherwise.
*/ */
public fun File.endsWith(other: File): Boolean { public fun File.endsWith(other: File): Boolean {
val components = toComponents() val components = toComponents()
val otherComponents = other.toComponents() val otherComponents = other.toComponents()
if (components.root != otherComponents.root && otherComponents.rootName != "") if (otherComponents.isRooted)
return false return this == other
val shift = components.size - otherComponents.size val shift = components.size - otherComponents.size
return if (shift < 0) false return if (shift < 0) false
else components.segments.subList(shift, components.size).equals(otherComponents.segments) else components.segments.subList(shift, components.size).equals(otherComponents.segments)
+11 -5
View File
@@ -243,8 +243,8 @@ class FilesTest {
assertTrue(File("/foo/bar").startsWith(File("/foo/bar"))) assertTrue(File("/foo/bar").startsWith(File("/foo/bar")))
assertTrue(File("/foo/bar").startsWith(File("/foo"))) assertTrue(File("/foo/bar").startsWith(File("/foo")))
assertTrue(File("/foo/bar").startsWith("/")) assertTrue(File("/foo/bar").startsWith("/"))
// TODO: assertFalse(File("/foo/bar").startsWith("")) assertFalse(File("/foo/bar").startsWith(""))
// TODO: assertFalse(File("/foo/bar").startsWith(File("foo"))) assertFalse(File("/foo/bar").startsWith(File("foo")))
assertFalse(File("/foo/bar").startsWith("/fo")) assertFalse(File("/foo/bar").startsWith("/fo"))
if (isBackslashSeparator) { if (isBackslashSeparator) {
@@ -259,9 +259,15 @@ class FilesTest {
@test fun endsWith() { @test fun endsWith() {
assertTrue(File("/foo/bar").endsWith("bar")) assertTrue(File("/foo/bar").endsWith("bar"))
assertTrue(File("/foo/bar").endsWith("/bar")) assertTrue(File("/foo/bar").endsWith("foo/bar"))
assertTrue(File("/foo/bar/gav/bar").endsWith("/bar")) assertTrue(File("/foo/bar").endsWith("/foo/bar"))
assertTrue(File("/foo/bar/gav/bar").endsWith("/gav/bar")) assertTrue(File("foo/bar").endsWith("foo/bar"))
assertTrue(File("foo/bar").endsWith("bar/"))
assertFalse(File("/foo/bar").endsWith("ar"))
assertFalse(File("/foo/bar").endsWith("/bar"))
assertFalse(File("/foo/bar/gav/bar").endsWith("/bar"))
assertFalse(File("/foo/bar/gav/bar").endsWith("/gav/bar"))
assertFalse(File("/foo/bar/gav").endsWith("/bar")) assertFalse(File("/foo/bar/gav").endsWith("/bar"))
assertFalse(File("foo/bar").endsWith("/bar")) assertFalse(File("foo/bar").endsWith("/bar"))
if (isCaseInsensitiveFileSystem) { if (isCaseInsensitiveFileSystem) {