Do not convert separatorsToSystem in file path extensions.
Do not require network host in network share root to contain dot. File.root now is always non-null to be consistent with File.toComponents().root. Introduce invariantSeparatorsPath property. Deprecate relativeTo to make it return File later. Introduce toRelativeString instead. Introduce relativeToOrNull and relativeToOrSelf extensions.
This commit is contained in:
@@ -29,12 +29,11 @@ private fun String.getRootName(): String {
|
|||||||
// So in Windows we'll have root of //my.host/home but in Unix just /
|
// So in Windows we'll have root of //my.host/home but in Unix just /
|
||||||
first = indexOf(File.separatorChar, 2)
|
first = indexOf(File.separatorChar, 2)
|
||||||
if (first >= 0) {
|
if (first >= 0) {
|
||||||
val dot = indexOf('.', 2)
|
first = indexOf(File.separatorChar, first + 1)
|
||||||
if (dot >= 0 && dot < first) {
|
if (first >= 0)
|
||||||
first = indexOf(File.separatorChar, first + 1)
|
return substring(0, first + 1)
|
||||||
if (first >= 0)
|
else
|
||||||
return substring(0, first + 1)
|
return this
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return substring(0, 1)
|
return substring(0, 1)
|
||||||
@@ -65,18 +64,23 @@ private fun String.getRootName(): String {
|
|||||||
* @return string representing the root for this file, or empty string is this file name is relative.
|
* @return string representing the root for this file, or empty string is this file name is relative.
|
||||||
*/
|
*/
|
||||||
public val File.rootName: String
|
public val File.rootName: String
|
||||||
get() = separatorsToSystem().getRootName()
|
get() = path.getRootName()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns root component of this abstract name, like / from /home/user, or C:\ from C:\file.tmp,
|
* Returns root component of this abstract name, like / from /home/user, or C:\ from C:\file.tmp,
|
||||||
* or //my.host/home for //my.host/home/user,
|
* or //my.host/home for //my.host/home/user
|
||||||
* or `null` if this name is relative, like bar/gav
|
|
||||||
*/
|
*/
|
||||||
public val File.root: File?
|
public val File.root: File
|
||||||
get() {
|
get() = File(rootName)
|
||||||
val name = rootName
|
|
||||||
return if (name.length > 0) File(name) else null
|
/**
|
||||||
}
|
* Determines whether this file has a root or it represents a relative path.
|
||||||
|
*
|
||||||
|
* Returns `true` when this file has non-empty root.
|
||||||
|
*/
|
||||||
|
public val File.isRooted: Boolean
|
||||||
|
// TODO: Do not calculate root
|
||||||
|
get() = path.getRootName().isNotEmpty()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the path to a file as a collection of directories.
|
* Represents the path to a file as a collection of directories.
|
||||||
@@ -91,12 +95,19 @@ public data class FilePathComponents
|
|||||||
@Deprecated("This constructor will be removed soon. Use File.toComponents() extension to create an instance of FilePathComponents.")
|
@Deprecated("This constructor will be removed soon. Use File.toComponents() extension to create an instance of FilePathComponents.")
|
||||||
constructor (rootName: String, fileList: List<File>): this(File(rootName), fileList)
|
constructor (rootName: String, fileList: List<File>): this(File(rootName), fileList)
|
||||||
|
|
||||||
@Deprecated("Use 'root' property or 'root.path' instead.", ReplaceWith("root.path"))
|
|
||||||
public val rootName: String get() = root.path
|
|
||||||
|
|
||||||
@Deprecated("Use 'segments' property instead.", ReplaceWith("segments"))
|
@Deprecated("Use 'segments' property instead.", ReplaceWith("segments"))
|
||||||
public val fileList: List<File> get() = segments
|
public val fileList: List<File> get() = segments
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representing the root for this file, or an empty string is this file name is relative.
|
||||||
|
*/
|
||||||
|
public val rootName: String get() = root.path
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns `true` when the [root] is not empty.
|
||||||
|
*/
|
||||||
|
public val isRooted: Boolean get() = root.path.isNotEmpty()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of elements in the path to the file.
|
* Returns the number of elements in the path to the file.
|
||||||
*/
|
*/
|
||||||
@@ -122,7 +133,7 @@ public data class FilePathComponents
|
|||||||
* itself) and returns the resulting collection of components.
|
* itself) and returns the resulting collection of components.
|
||||||
*/
|
*/
|
||||||
public fun File.toComponents(): FilePathComponents {
|
public fun File.toComponents(): FilePathComponents {
|
||||||
val path = separatorsToSystem()
|
val path = path
|
||||||
val rootName = path.getRootName()
|
val rootName = path.getRootName()
|
||||||
val subPath = path.substring(rootName.length)
|
val subPath = path.substring(rootName.length)
|
||||||
// if: a special case when we have only root component
|
// if: a special case when we have only root component
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public val File.extension: String
|
|||||||
*
|
*
|
||||||
* @return the pathname with system separators.
|
* @return the pathname with system separators.
|
||||||
*/
|
*/
|
||||||
@Deprecated("Use File.separatorsToSystem instead", ReplaceWith("File(this).separatorsToSystem()", "java.io.File"))
|
@Deprecated("Use File.path instead", ReplaceWith("File(this).path", "java.io.File"))
|
||||||
public fun String.separatorsToSystem(): String {
|
public fun String.separatorsToSystem(): String {
|
||||||
val otherSep = if (File.separator == "/") "\\" else "/"
|
val otherSep = if (File.separator == "/") "\\" else "/"
|
||||||
return replace(otherSep, File.separator)
|
return replace(otherSep, File.separator)
|
||||||
@@ -101,10 +101,18 @@ public fun String.allSeparatorsToSystem(): String {
|
|||||||
*
|
*
|
||||||
* @return the pathname with system separators.
|
* @return the pathname with system separators.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("File has already system separators.")
|
||||||
public fun File.separatorsToSystem(): String {
|
public fun File.separatorsToSystem(): String {
|
||||||
return toString().separatorsToSystem()
|
return toString().separatorsToSystem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns [path] of this File using the invariant separator '/' to
|
||||||
|
* separate the names in the name sequence.
|
||||||
|
*/
|
||||||
|
public val File.invariantSeparatorsPath: String
|
||||||
|
get() = if (File.separatorChar != '/') path.replace(File.separatorChar, '/') else path
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns file's name without an extension.
|
* Returns file's name without an extension.
|
||||||
*/
|
*/
|
||||||
@@ -118,16 +126,60 @@ public val File.nameWithoutExtension: String
|
|||||||
*
|
*
|
||||||
* @return relative path from [base] to this.
|
* @return relative path from [base] to this.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if child and parent have different roots.
|
* @throws IllegalArgumentException if this and base paths have different roots.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("This function will change return type to File soon. Use toRelativeString instead.", ReplaceWith("toRelativeString(base)"))
|
||||||
public fun File.relativeTo(base: File): String
|
public fun File.relativeTo(base: File): String
|
||||||
= relativeToOrNull(base) ?: throw IllegalArgumentException("this and base files have different roots: $this and $base")
|
= toRelativeString(base)
|
||||||
|
|
||||||
// TODO
|
|
||||||
//private fun File.relativeToOrPath(base: File): String
|
|
||||||
// = relativeToOrNull(base) ?: toString()
|
|
||||||
|
|
||||||
private fun File.relativeToOrNull(base: File): String? {
|
/**
|
||||||
|
* Calculates the relative path for this file from [base] file.
|
||||||
|
* Note that the [base] file is treated as a directory.
|
||||||
|
* If this file matches the [base] file, then an empty string will be returned.
|
||||||
|
*
|
||||||
|
* @return relative path from [base] to this.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if this and base paths have different roots.
|
||||||
|
*/
|
||||||
|
public fun File.toRelativeString(base: File): String
|
||||||
|
= toRelativeStringOrNull(base) ?: throw IllegalArgumentException("this and base files have different roots: $this and $base")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the relative path for this file from [base] file.
|
||||||
|
* Note that the [base] file is treated as a directory.
|
||||||
|
* If this file matches the [base] file, then a [File] with empty path will be returned.
|
||||||
|
*
|
||||||
|
* @return File with relative path from [base] to this.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException if this and base paths have different roots.
|
||||||
|
*/
|
||||||
|
@Deprecated("This function will be renamed to relativeTo soon.")
|
||||||
|
public fun File.relativeToFile(base: File): File = File(this.relativeTo(base))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the relative path for this file from [base] file.
|
||||||
|
* Note that the [base] file is treated as a directory.
|
||||||
|
* If this file matches the [base] file, then a [File] with empty path will be returned.
|
||||||
|
*
|
||||||
|
* @return File with relative path from [base] to this, or `this` if this and base paths have different roots.
|
||||||
|
*/
|
||||||
|
public fun File.relativeToOrSelf(base: File): File
|
||||||
|
= toRelativeStringOrNull(base)?.let { File(it) } ?: this
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the relative path for this file from [base] file.
|
||||||
|
* Note that the [base] file is treated as a directory.
|
||||||
|
* If this file matches the [base] file, then a [File] with empty path will be returned.
|
||||||
|
*
|
||||||
|
* @return File with relative path from [base] to this, or `null` if this and base paths have different roots.
|
||||||
|
*/
|
||||||
|
public fun File.relativeToOrNull(base: File): File?
|
||||||
|
= toRelativeStringOrNull(base)?.let { File(it) }
|
||||||
|
|
||||||
|
|
||||||
|
private fun File.toRelativeStringOrNull(base: File): String? {
|
||||||
// Check roots
|
// Check roots
|
||||||
val thisComponents = this.toComponents().normalize()
|
val thisComponents = this.toComponents().normalize()
|
||||||
val baseComponents = base.toComponents().normalize()
|
val baseComponents = base.toComponents().normalize()
|
||||||
@@ -411,7 +463,7 @@ private fun List<File>.normalize(): List<File> {
|
|||||||
* @return concatenated this and [relative] paths, or just [relative] if it's absolute.
|
* @return concatenated this and [relative] paths, or just [relative] if it's absolute.
|
||||||
*/
|
*/
|
||||||
public fun File.resolve(relative: File): File {
|
public fun File.resolve(relative: File): File {
|
||||||
if (relative.root != null)
|
if (relative.isRooted)
|
||||||
return relative
|
return relative
|
||||||
val baseName = this.toString()
|
val baseName = this.toString()
|
||||||
return if (baseName.isEmpty() || baseName.endsWith(File.separatorChar)) File(baseName + relative) else File(baseName + File.separatorChar + relative)
|
return if (baseName.isEmpty() || baseName.endsWith(File.separatorChar)) File(baseName + relative) else File(baseName + File.separatorChar + relative)
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ class FileTreeWalkTest {
|
|||||||
companion object {
|
companion object {
|
||||||
val referenceFilenames =
|
val referenceFilenames =
|
||||||
listOf("1", "1/2", "1/3", "1/3/4.txt", "1/3/5.txt", "6", "7.txt", "8", "8/9.txt")
|
listOf("1", "1/2", "1/3", "1/3/4.txt", "1/3/5.txt", "6", "7.txt", "8", "8/9.txt")
|
||||||
.map { it.separatorsToSystem() }
|
|
||||||
fun createTestFiles(): File {
|
fun createTestFiles(): File {
|
||||||
val basedir = createTempDir()
|
val basedir = createTempDir()
|
||||||
for (name in referenceFilenames) {
|
for (name in referenceFilenames) {
|
||||||
@@ -31,14 +30,14 @@ class FileTreeWalkTest {
|
|||||||
val referenceNames = setOf("") + referenceFilenames
|
val referenceNames = setOf("") + referenceFilenames
|
||||||
val namesTopDown = HashSet<String>()
|
val namesTopDown = HashSet<String>()
|
||||||
for (file in basedir.walkTopDown()) {
|
for (file in basedir.walkTopDown()) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||||
namesTopDown.add(name)
|
namesTopDown.add(name)
|
||||||
}
|
}
|
||||||
assertEquals(referenceNames, namesTopDown)
|
assertEquals(referenceNames, namesTopDown)
|
||||||
val namesBottomUp = HashSet<String>()
|
val namesBottomUp = HashSet<String>()
|
||||||
for (file in basedir.walkBottomUp()) {
|
for (file in basedir.walkBottomUp()) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
|
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
|
||||||
namesBottomUp.add(name)
|
namesBottomUp.add(name)
|
||||||
}
|
}
|
||||||
@@ -69,13 +68,12 @@ class FileTreeWalkTest {
|
|||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
val referenceNames =
|
val referenceNames =
|
||||||
listOf("", "1", "1/2", "6", "8").map(
|
setOf("", "1", "1/2", "6", "8")
|
||||||
{ it -> it.separatorsToSystem() }).toHashSet()
|
|
||||||
val namesTopDownEnter = HashSet<String>()
|
val namesTopDownEnter = HashSet<String>()
|
||||||
val namesTopDownLeave = HashSet<String>()
|
val namesTopDownLeave = HashSet<String>()
|
||||||
val namesTopDown = HashSet<String>()
|
val namesTopDown = HashSet<String>()
|
||||||
fun enter(file: File): Boolean {
|
fun enter(file: File): Boolean {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertTrue(file.isDirectory, "$name is not directory, only directories should be entered")
|
assertTrue(file.isDirectory, "$name is not directory, only directories should be entered")
|
||||||
assertFalse(namesTopDownEnter.contains(name), "$name is entered twice")
|
assertFalse(namesTopDownEnter.contains(name), "$name is entered twice")
|
||||||
assertFalse(namesTopDownLeave.contains(name), "$name is left before entrance")
|
assertFalse(namesTopDownLeave.contains(name), "$name is left before entrance")
|
||||||
@@ -85,7 +83,7 @@ class FileTreeWalkTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun leave(file: File) {
|
fun leave(file: File) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertTrue(file.isDirectory, "$name is not directory, only directories should be left")
|
assertTrue(file.isDirectory, "$name is not directory, only directories should be left")
|
||||||
assertFalse(namesTopDownLeave.contains(name), "$name is left twice")
|
assertFalse(namesTopDownLeave.contains(name), "$name is left twice")
|
||||||
namesTopDownLeave.add(name)
|
namesTopDownLeave.add(name)
|
||||||
@@ -93,7 +91,7 @@ class FileTreeWalkTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun visit(file: File) {
|
fun visit(file: File) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
if (file.isDirectory) {
|
if (file.isDirectory) {
|
||||||
assertTrue(namesTopDownEnter.contains(name), "$name is visited before entrance")
|
assertTrue(namesTopDownEnter.contains(name), "$name is visited before entrance")
|
||||||
namesTopDown.add(name)
|
namesTopDown.add(name)
|
||||||
@@ -103,7 +101,7 @@ class FileTreeWalkTest {
|
|||||||
return
|
return
|
||||||
val parent = file.parentFile
|
val parent = file.parentFile
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
val parentName = parent.relativeTo(basedir)
|
val parentName = parent.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertTrue(namesTopDownEnter.contains(parentName),
|
assertTrue(namesTopDownEnter.contains(parentName),
|
||||||
"$name is visited before entering its parent $parentName")
|
"$name is visited before entering its parent $parentName")
|
||||||
assertFalse(namesTopDownLeave.contains(parentName),
|
assertFalse(namesTopDownLeave.contains(parentName),
|
||||||
@@ -131,11 +129,9 @@ class FileTreeWalkTest {
|
|||||||
@Test fun withFilterAndMap() {
|
@Test fun withFilterAndMap() {
|
||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
val referenceNames =
|
val referenceNames = setOf("", "1", "1/2", "1/3", "6", "8")
|
||||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
|
||||||
{ it -> it.separatorsToSystem() }).toHashSet()
|
|
||||||
assertEquals(referenceNames, basedir.walkTopDown().filter { it.isDirectory() }.map {
|
assertEquals(referenceNames, basedir.walkTopDown().filter { it.isDirectory() }.map {
|
||||||
it.relativeTo(basedir)
|
it.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
}.toHashSet())
|
}.toHashSet())
|
||||||
} finally {
|
} finally {
|
||||||
basedir.deleteRecursively()
|
basedir.deleteRecursively()
|
||||||
@@ -146,9 +142,7 @@ class FileTreeWalkTest {
|
|||||||
@Test fun withDeleteTxtTopDown() {
|
@Test fun withDeleteTxtTopDown() {
|
||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
val referenceNames =
|
val referenceNames = setOf("", "1", "1/2", "1/3", "6", "8")
|
||||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
|
||||||
{ it -> it.separatorsToSystem() }).toHashSet()
|
|
||||||
val namesTopDown = HashSet<String>()
|
val namesTopDown = HashSet<String>()
|
||||||
fun enter(file: File) {
|
fun enter(file: File) {
|
||||||
assertTrue(file.isDirectory())
|
assertTrue(file.isDirectory())
|
||||||
@@ -158,7 +152,7 @@ class FileTreeWalkTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (file in basedir.walkTopDown().enter(::enter)) {
|
for (file in basedir.walkTopDown().enter(::enter)) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||||
namesTopDown.add(name)
|
namesTopDown.add(name)
|
||||||
}
|
}
|
||||||
@@ -171,9 +165,7 @@ class FileTreeWalkTest {
|
|||||||
@Test fun withDeleteTxtBottomUp() {
|
@Test fun withDeleteTxtBottomUp() {
|
||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
val referenceNames =
|
val referenceNames = setOf("", "1", "1/2", "1/3", "6", "8")
|
||||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
|
||||||
{ it -> it.separatorsToSystem() }).toHashSet()
|
|
||||||
val namesTopDown = HashSet<String>()
|
val namesTopDown = HashSet<String>()
|
||||||
fun enter(file: File) {
|
fun enter(file: File) {
|
||||||
assertTrue(file.isDirectory())
|
assertTrue(file.isDirectory())
|
||||||
@@ -183,7 +175,7 @@ class FileTreeWalkTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (file in basedir.walkBottomUp().enter(::enter)) {
|
for (file in basedir.walkBottomUp().enter(::enter)) {
|
||||||
val name = file.relativeTo(basedir)
|
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
|
||||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||||
namesTopDown.add(name)
|
namesTopDown.add(name)
|
||||||
}
|
}
|
||||||
@@ -270,13 +262,13 @@ class FileTreeWalkTest {
|
|||||||
@Test fun withVisitorAndDepth() {
|
@Test fun withVisitorAndDepth() {
|
||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
val files = HashSet<String>()
|
val files = HashSet<File>()
|
||||||
val dirs = HashSet<String>()
|
val dirs = HashSet<File>()
|
||||||
val failed = HashSet<String>()
|
val failed = HashSet<String>()
|
||||||
val stack = ArrayList<File>()
|
val stack = ArrayList<File>()
|
||||||
fun beforeVisitDirectory(dir: File) {
|
fun beforeVisitDirectory(dir: File) {
|
||||||
stack.add(dir)
|
stack.add(dir)
|
||||||
dirs.add(dir.relativeTo(basedir))
|
dirs.add(dir.relativeToOrSelf(basedir))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun afterVisitDirectory(dir: File) {
|
fun afterVisitDirectory(dir: File) {
|
||||||
@@ -286,7 +278,7 @@ class FileTreeWalkTest {
|
|||||||
|
|
||||||
fun visitFile(file: File) {
|
fun visitFile(file: File) {
|
||||||
assert(stack.last().listFiles().contains(file)) { file }
|
assert(stack.last().listFiles().contains(file)) { file }
|
||||||
files.add(file.relativeTo(basedir))
|
files.add(file.relativeToOrSelf(basedir))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visitDirectoryFailed(dir: File, e: IOException) {
|
fun visitDirectoryFailed(dir: File, e: IOException) {
|
||||||
@@ -298,10 +290,10 @@ class FileTreeWalkTest {
|
|||||||
fail(::visitDirectoryFailed).forEach { it -> if (!it.isDirectory()) visitFile(it) }
|
fail(::visitDirectoryFailed).forEach { it -> if (!it.isDirectory()) visitFile(it) }
|
||||||
assert(stack.isEmpty())
|
assert(stack.isEmpty())
|
||||||
val sep = File.separator
|
val sep = File.separator
|
||||||
for (fileName in arrayOf("", "1", "1${sep}2", "1${sep}3", "6", "8")) {
|
for (fileName in arrayOf("", "1", "1/2", "1/3", "6", "8")) {
|
||||||
assert(dirs.contains(fileName)) { fileName }
|
assert(dirs.contains(fileName)) { fileName }
|
||||||
}
|
}
|
||||||
for (fileName in arrayOf("1${sep}3${sep}4.txt", "1${sep}3${sep}4.txt", "7.txt", "8${sep}9.txt")) {
|
for (fileName in arrayOf("1/3/4.txt", "1/3/4.txt", "7.txt", "8/9.txt")) {
|
||||||
assert(files.contains(fileName)) { fileName }
|
assert(files.contains(fileName)) { fileName }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,9 +303,9 @@ class FileTreeWalkTest {
|
|||||||
basedir.walkTopDown().enter(::beforeVisitDirectory).leave(::afterVisitDirectory).maxDepth(1).
|
basedir.walkTopDown().enter(::beforeVisitDirectory).leave(::afterVisitDirectory).maxDepth(1).
|
||||||
forEach { it -> if (it != basedir) visitFile(it) }
|
forEach { it -> if (it != basedir) visitFile(it) }
|
||||||
assert(stack.isEmpty())
|
assert(stack.isEmpty())
|
||||||
assert(dirs.size == 1 && dirs.contains("")) { dirs.size }
|
assert(dirs.size == 1 && dirs.contains(File(""))) { dirs.size }
|
||||||
for (file in arrayOf("1", "6", "7.txt", "8")) {
|
for (file in arrayOf("1", "6", "7.txt", "8")) {
|
||||||
assert(files.contains(file)) { file }
|
assert(files.contains(File(file))) { file }
|
||||||
}
|
}
|
||||||
|
|
||||||
//restrict access
|
//restrict access
|
||||||
@@ -327,11 +319,11 @@ class FileTreeWalkTest {
|
|||||||
assert(failed.size == 1 && failed.contains("1")) { failed.size }
|
assert(failed.size == 1 && failed.contains("1")) { failed.size }
|
||||||
assert(dirs.size == 4) { dirs.size }
|
assert(dirs.size == 4) { dirs.size }
|
||||||
for (dir in arrayOf("", "1", "6", "8")) {
|
for (dir in arrayOf("", "1", "6", "8")) {
|
||||||
assert(dirs.contains(dir)) { dir }
|
assert(dirs.contains(File(dir))) { dir }
|
||||||
}
|
}
|
||||||
assert(files.size == 2) { files.size }
|
assert(files.size == 2) { files.size }
|
||||||
for (file in arrayOf("7.txt", "8${sep}9.txt")) {
|
for (file in arrayOf("7.txt", "8/9.txt")) {
|
||||||
assert(files.contains(file)) { file }
|
assert(files.contains(File(file))) { file }
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
File(basedir, "1").setReadable(true)
|
File(basedir, "1").setReadable(true)
|
||||||
@@ -418,7 +410,7 @@ class FileTreeWalkTest {
|
|||||||
@Test fun find() {
|
@Test fun find() {
|
||||||
val basedir = createTestFiles()
|
val basedir = createTestFiles()
|
||||||
try {
|
try {
|
||||||
File(basedir, "8/4.txt".separatorsToSystem()).createNewFile()
|
File(basedir, "8/4.txt").createNewFile()
|
||||||
var count = 0
|
var count = 0
|
||||||
basedir.walkTopDown().takeWhile { it -> count == 0 }.forEach {
|
basedir.walkTopDown().takeWhile { it -> count == 0 }.forEach {
|
||||||
if (it.name == "4.txt") {
|
if (it.name == "4.txt") {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class FilesTest {
|
|||||||
val file1 = File("/foo/bar/baz")
|
val file1 = File("/foo/bar/baz")
|
||||||
val file2 = File("/foo/baa/ghoo")
|
val file2 = File("/foo/baa/ghoo")
|
||||||
|
|
||||||
assertEquals("../../bar/baz".separatorsToSystem(), file1.relativeTo(file2))
|
assertEquals("../../bar/baz", file1.relativeToFile(file2).invariantSeparatorsPath)
|
||||||
|
|
||||||
val file3 = File("/foo/bar")
|
val file3 = File("/foo/bar")
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ class FilesTest {
|
|||||||
|
|
||||||
val file5 = File("/foo/baran")
|
val file5 = File("/foo/baran")
|
||||||
|
|
||||||
assertEquals("../bar".separatorsToSystem(), file3.relativeTo(file5))
|
assertEquals("../bar", file3.relativeToFile(file5).invariantSeparatorsPath)
|
||||||
assertEquals("../baran".separatorsToSystem(), file5.relativeTo(file3))
|
assertEquals("../baran", file5.relativeToFile(file3).invariantSeparatorsPath)
|
||||||
assertEquals("../bar".separatorsToSystem(), file4.relativeTo(file5))
|
assertEquals("../bar", file4.relativeToFile(file5).invariantSeparatorsPath)
|
||||||
assertEquals("../baran".separatorsToSystem(), file5.relativeTo(file4))
|
assertEquals("../baran", file5.relativeToFile(file4).invariantSeparatorsPath)
|
||||||
|
|
||||||
val file6 = File("C:\\Users\\Me")
|
val file6 = File("C:\\Users\\Me")
|
||||||
val file7 = File("C:\\Users\\Me\\Documents")
|
val file7 = File("C:\\Users\\Me\\Documents")
|
||||||
@@ -109,8 +109,8 @@ class FilesTest {
|
|||||||
val file8 = File("""\\my.host\home/user/documents/vip""")
|
val file8 = File("""\\my.host\home/user/documents/vip""")
|
||||||
val file9 = File("""\\my.host\home/other/images/nice""")
|
val file9 = File("""\\my.host\home/other/images/nice""")
|
||||||
|
|
||||||
assertEquals("../../../user/documents/vip".separatorsToSystem(), file8.relativeTo(file9))
|
assertEquals("../../../user/documents/vip", file8.relativeToFile(file9).invariantSeparatorsPath)
|
||||||
assertEquals("../../../other/images/nice".separatorsToSystem(), file9.relativeTo(file8))
|
assertEquals("../../../other/images/nice", file9.relativeToFile(file8).invariantSeparatorsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test fun relativeToRelative() {
|
@test fun relativeToRelative() {
|
||||||
@@ -165,56 +165,66 @@ class FilesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assertFailsRelativeTo(File("y"), File("../x"))
|
assertFailsRelativeTo(File("y"), File("../x"))
|
||||||
|
|
||||||
|
// This test operates correctly only at Windows PCs with C & D drives
|
||||||
|
val fileOnC = File("C:/dir1")
|
||||||
|
val fileOnD = File("D:/dir2")
|
||||||
|
assertFailsRelativeTo(fileOnC, fileOnD)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test fun relativeTo() {
|
@test fun relativeTo() {
|
||||||
assertEquals("kotlin", File("src/kotlin".separatorsToSystem()).relativeTo(File("src")))
|
assertEquals("kotlin", File("src/kotlin").relativeTo(File("src")))
|
||||||
assertEquals("", File("dir").relativeTo(File("dir")))
|
assertEquals("", File("dir").relativeTo(File("dir")))
|
||||||
assertEquals("..", File("dir").relativeTo(File("dir/subdir".separatorsToSystem())))
|
assertEquals("..", File("dir").relativeTo(File("dir/subdir")))
|
||||||
assertEquals("../../test".separatorsToSystem(), File("test").relativeTo(File("dir/dir".separatorsToSystem())))
|
assertEquals(File("../../test"), File("test").relativeToFile(File("dir/dir")))
|
||||||
|
|
||||||
// This test operates correctly only at Windows PCs with C & D drives
|
|
||||||
val file1 = File("C:/dir1".separatorsToSystem())
|
|
||||||
val file2 = File("D:/dir2".separatorsToSystem())
|
|
||||||
try {
|
|
||||||
file1.relativeTo(file2)
|
|
||||||
assert(false);
|
|
||||||
} catch (e: IllegalArgumentException) {
|
|
||||||
// It's the thing we should get here
|
|
||||||
} catch (e: IOException) {
|
|
||||||
// The device is not ready (D) ==> DO NOTHING
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFileElements(f: File, root: File?, elements: List<String>) {
|
private fun checkFilePathComponents(f: File, root: File, elements: List<String>) {
|
||||||
var i = 0
|
|
||||||
assertEquals(root, f.root)
|
assertEquals(root, f.root)
|
||||||
for (elem in f.toComponents().segments) {
|
val components = f.toComponents()
|
||||||
assertTrue(i < elements.size, i.toString())
|
assertEquals(root, components.root)
|
||||||
assertEquals(elements[i++], elem.toString())
|
assertEquals(elements, components.segments.map { it.toString() })
|
||||||
}
|
|
||||||
assertEquals(elements.size, i)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test fun fileIterator() {
|
@test fun filePathComponents() {
|
||||||
checkFileElements(File("/foo/bar"), File("/"), listOf("foo", "bar"))
|
checkFilePathComponents(File("/foo/bar"), File("/"), listOf("foo", "bar"))
|
||||||
checkFileElements(File("\\foo\\bar"), File("\\".separatorsToSystem()), listOf("foo", "bar"))
|
checkFilePathComponents(File("/foo/bar/gav"), File("/"), listOf("foo", "bar", "gav"))
|
||||||
checkFileElements(File("/foo/bar/gav"), File("/"), listOf("foo", "bar", "gav"))
|
checkFilePathComponents(File("/foo/bar/gav/"), File("/"), listOf("foo", "bar", "gav"))
|
||||||
checkFileElements(File("/foo/bar/gav/"), File("/"), listOf("foo", "bar", "gav"))
|
checkFilePathComponents(File("bar/gav"), File(""), listOf("bar", "gav"))
|
||||||
checkFileElements(File("bar/gav"), null, listOf("bar", "gav"))
|
checkFilePathComponents(File("C:/bar/gav"), File("C:/"), listOf("bar", "gav"))
|
||||||
checkFileElements(File("C:\\bar\\gav"), File("C:\\".separatorsToSystem()), listOf("bar", "gav"))
|
checkFilePathComponents(File("C:/"), File("C:/"), listOf())
|
||||||
checkFileElements(File("C:/bar/gav"), File("C:/"), listOf("bar", "gav"))
|
checkFilePathComponents(File("C:"), File("C:"), listOf())
|
||||||
checkFileElements(File("C:\\"), File("C:\\".separatorsToSystem()), listOf())
|
if (File.separator == "\\") {
|
||||||
checkFileElements(File("C:/"), File("C:/"), listOf())
|
|
||||||
checkFileElements(File("C:"), File("C:"), listOf())
|
|
||||||
if (File.separatorChar == '\\') {
|
|
||||||
// Check only in Windows
|
// Check only in Windows
|
||||||
checkFileElements(File("\\\\host.ru\\home\\mike"), File("\\\\host.ru\\home"), listOf("mike"))
|
checkFilePathComponents(File("\\\\host.ru\\home\\mike"), File("\\\\host.ru\\home"), listOf("mike"))
|
||||||
checkFileElements(File("//host.ru/home/mike"), File("//host.ru/home"), listOf("mike"))
|
checkFilePathComponents(File("//host.ru/home/mike"), File("//host.ru/home"), listOf("mike"))
|
||||||
|
checkFilePathComponents(File("\\foo\\bar"), File("\\"), listOf("foo", "bar"))
|
||||||
|
checkFilePathComponents(File("C:\\bar\\gav"), File("C:\\"), listOf("bar", "gav"))
|
||||||
|
checkFilePathComponents(File("C:\\"), File("C:\\"), listOf())
|
||||||
}
|
}
|
||||||
checkFileElements(File(""), null, listOf())
|
checkFilePathComponents(File(""), File(""), listOf())
|
||||||
checkFileElements(File("."), null, listOf("."))
|
checkFilePathComponents(File("."), File(""), listOf("."))
|
||||||
checkFileElements(File(".."), null, listOf(".."))
|
checkFilePathComponents(File(".."), File(""), listOf(".."))
|
||||||
|
}
|
||||||
|
|
||||||
|
@test fun fileRoot() {
|
||||||
|
val rooted = File("/foo/bar")
|
||||||
|
assertTrue(rooted.isRooted)
|
||||||
|
assertEquals("/", rooted.root.invariantSeparatorsPath)
|
||||||
|
|
||||||
|
if (File.separator == "\\") {
|
||||||
|
val diskRooted = File("""C:\foo\bar""")
|
||||||
|
assertTrue(rooted.isRooted)
|
||||||
|
assertEquals("""C:\""", diskRooted.rootName)
|
||||||
|
|
||||||
|
val networkRooted = File("""\\network\share\""")
|
||||||
|
assertTrue(networkRooted.isRooted)
|
||||||
|
assertEquals("""\\network\share""", networkRooted.rootName)
|
||||||
|
}
|
||||||
|
|
||||||
|
val relative = File("foo/bar")
|
||||||
|
assertFalse(relative.isRooted)
|
||||||
|
assertEquals("", relative.rootName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@test fun startsWith() {
|
@test fun startsWith() {
|
||||||
@@ -254,9 +264,10 @@ class FilesTest {
|
|||||||
assertEquals(File("/foo/bar/baaz"), File("/foo/bak/../bar/gav/../baaz").normalize())
|
assertEquals(File("/foo/bar/baaz"), File("/foo/bak/../bar/gav/../baaz").normalize())
|
||||||
assertEquals(File("../../bar"), File("../foo/../../bar").normalize())
|
assertEquals(File("../../bar"), File("../foo/../../bar").normalize())
|
||||||
// For Unix C:\windows is not correct so it's not the same as C:/windows
|
// For Unix C:\windows is not correct so it's not the same as C:/windows
|
||||||
assertEquals(File("C:\\windows").separatorsToSystem(),
|
if (File.separator == "\\") {
|
||||||
File("C:\\home\\..\\documents\\..\\windows").normalize().separatorsToSystem())
|
assertEquals(File("C:\\windows"), File("C:\\home\\..\\documents\\..\\windows").normalize())
|
||||||
assertEquals(File("C:/windows"), File("C:/home/../documents/../windows").normalize())
|
assertEquals(File("C:/windows"), File("C:/home/../documents/../windows").normalize())
|
||||||
|
}
|
||||||
assertEquals(File("foo"), File("gav/bar/../../foo").normalize())
|
assertEquals(File("foo"), File("gav/bar/../../foo").normalize())
|
||||||
assertEquals(File("/../foo"), File("/bar/../../foo").normalize())
|
assertEquals(File("/../foo"), File("/bar/../../foo").normalize())
|
||||||
}
|
}
|
||||||
@@ -266,11 +277,12 @@ class FilesTest {
|
|||||||
assertEquals(File("/foo/bar/gav"), File("/foo/bar/").resolve("gav"))
|
assertEquals(File("/foo/bar/gav"), File("/foo/bar/").resolve("gav"))
|
||||||
assertEquals(File("/gav"), File("/foo/bar").resolve("/gav"))
|
assertEquals(File("/gav"), File("/foo/bar").resolve("/gav"))
|
||||||
// For Unix C:\path is not correct so it's cannot be automatically converted
|
// For Unix C:\path is not correct so it's cannot be automatically converted
|
||||||
assertEquals(File("C:\\Users\\Me\\Documents\\important.doc").separatorsToSystem(),
|
if (File.separator == "\\") {
|
||||||
File("C:\\Users\\Me").resolve("Documents\\important.doc").separatorsToSystem())
|
assertEquals(File("C:\\Users\\Me\\Documents\\important.doc"),
|
||||||
assertEquals(File("C:/Users/Me/Documents/important.doc"),
|
File("C:\\Users\\Me").resolve("Documents\\important.doc"))
|
||||||
File("C:/Users/Me").resolve("Documents/important.doc"))
|
assertEquals(File("C:/Users/Me/Documents/important.doc"),
|
||||||
|
File("C:/Users/Me").resolve("Documents/important.doc"))
|
||||||
|
}
|
||||||
assertEquals(File(""), File("").resolve(""))
|
assertEquals(File(""), File("").resolve(""))
|
||||||
assertEquals(File("bar"), File("").resolve("bar"))
|
assertEquals(File("bar"), File("").resolve("bar"))
|
||||||
assertEquals(File("foo/bar"), File("foo").resolve("bar"))
|
assertEquals(File("foo/bar"), File("foo").resolve("bar"))
|
||||||
@@ -285,10 +297,12 @@ class FilesTest {
|
|||||||
assertEquals(File("/foo/gav"), File("/foo/bar/").resolveSibling("gav"))
|
assertEquals(File("/foo/gav"), File("/foo/bar/").resolveSibling("gav"))
|
||||||
assertEquals(File("/gav"), File("/foo/bar").resolveSibling("/gav"))
|
assertEquals(File("/gav"), File("/foo/bar").resolveSibling("/gav"))
|
||||||
// For Unix C:\path is not correct so it's cannot be automatically converted
|
// For Unix C:\path is not correct so it's cannot be automatically converted
|
||||||
assertEquals(File("C:\\Users\\Me\\Documents\\important.doc").separatorsToSystem(),
|
if (File.separator == "\\") {
|
||||||
File("C:\\Users\\Me\\profile.ini").resolveSibling("Documents\\important.doc").separatorsToSystem())
|
assertEquals(File("C:\\Users\\Me\\Documents\\important.doc"),
|
||||||
assertEquals(File("C:/Users/Me/Documents/important.doc"),
|
File("C:\\Users\\Me\\profile.ini").resolveSibling("Documents\\important.doc"))
|
||||||
File("C:/Users/Me/profile.ini").resolveSibling("Documents/important.doc"))
|
assertEquals(File("C:/Users/Me/Documents/important.doc"),
|
||||||
|
File("C:/Users/Me/profile.ini").resolveSibling("Documents/important.doc"))
|
||||||
|
}
|
||||||
assertEquals(File("gav"), File("foo").resolveSibling("gav"))
|
assertEquals(File("gav"), File("foo").resolveSibling("gav"))
|
||||||
assertEquals(File("../gav"), File("").resolveSibling("gav"))
|
assertEquals(File("../gav"), File("").resolveSibling("gav"))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user