Kotlin I/O new features: relativeTo, copyTo, copyRecursively, deleteRecursively, file tree walkers,
file component iterators, file roots, startsWith, endsWith, subPath, normalize, replaceBytes, replaceTest, additional tests and comments
This commit is contained in:
committed by
Mikhail Glukhikh
parent
dae42f7c76
commit
f560677b15
@@ -1,52 +1,582 @@
|
||||
package test.io
|
||||
|
||||
import org.junit.Test as test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.NoSuchElementException
|
||||
import java.util.HashSet
|
||||
import java.util.ArrayList
|
||||
import kotlin.io.files.walkBottomUp
|
||||
import kotlin.io.files.walkTopDown
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class FilesTest {
|
||||
test fun listFilesWithFilter() {
|
||||
val dir = File.createTempFile("temp", System.nanoTime().toString())
|
||||
dir.delete()
|
||||
dir.mkdir()
|
||||
|
||||
File.createTempFile("temp1", ".kt", dir)
|
||||
File.createTempFile("temp2", ".java", dir)
|
||||
File.createTempFile("temp3", ".kt", dir)
|
||||
test fun testPath() {
|
||||
val fileSuf = System.currentTimeMillis().toString()
|
||||
val file1 = createTempFile("temp", fileSuf)
|
||||
assertTrue(file1.path.endsWith(fileSuf), file1.path)
|
||||
}
|
||||
|
||||
test fun testCreateTempDir() {
|
||||
val dirSuf = System.currentTimeMillis().toString()
|
||||
val dir1 = createTempDir("temp", dirSuf)
|
||||
assert(dir1.exists() && dir1.isDirectory() && dir1.name.startsWith("temp") && dir1.name.endsWith(dirSuf))
|
||||
try {
|
||||
createTempDir("a")
|
||||
assert(false)
|
||||
} catch(e: IllegalArgumentException) {}
|
||||
|
||||
val dir2 = createTempDir("temp")
|
||||
assert(dir2.exists() && dir2.isDirectory() && dir2.name.endsWith(".tmp"))
|
||||
|
||||
val dir3 = createTempDir()
|
||||
assert(dir3.exists() && dir3.isDirectory())
|
||||
|
||||
dir1.delete()
|
||||
dir2.delete()
|
||||
dir3.delete()
|
||||
}
|
||||
|
||||
test fun testCreateTempFile() {
|
||||
val fileSuf = System.currentTimeMillis().toString()
|
||||
val file1 = createTempFile("temp", fileSuf)
|
||||
assert(file1.exists() && file1.name.startsWith("temp") && file1.name.endsWith(fileSuf))
|
||||
try {
|
||||
createTempFile("a")
|
||||
assert(false)
|
||||
} catch(e: IllegalArgumentException) {}
|
||||
val file2 = createTempFile("temp")
|
||||
assert(file2.exists() && file2.name.endsWith(".tmp"))
|
||||
|
||||
val file3 = createTempFile()
|
||||
assert(file3.exists())
|
||||
|
||||
file1.delete()
|
||||
file2.delete()
|
||||
file3.delete()
|
||||
}
|
||||
|
||||
class Walks {
|
||||
fun createTestFiles(): File {
|
||||
val basedir = createTempDir()
|
||||
File(basedir, "1").mkdir()
|
||||
File(basedir, "1/2".separatorsToSystem()).mkdir()
|
||||
File(basedir, "1/3".separatorsToSystem()).mkdir()
|
||||
File(basedir, "1/3/4.txt".separatorsToSystem()).createNewFile()
|
||||
File(basedir, "1/3/5.txt".separatorsToSystem()).createNewFile()
|
||||
File(basedir, "6").mkdir()
|
||||
File(basedir, "7.txt").createNewFile()
|
||||
File(basedir, "8").mkdir()
|
||||
File(basedir, "8/9.txt".separatorsToSystem()).createNewFile()
|
||||
return basedir
|
||||
}
|
||||
|
||||
test fun withSimple() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "1/3", "1/3/4.txt", "1/3/5.txt", "6", "7.txt", "8", "8/9.txt").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
val namesTopDown = HashSet<String>()
|
||||
for (file in basedir.walkTopDown()) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||
namesTopDown.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDown)
|
||||
val namesBottomUp = HashSet<String>()
|
||||
for (file in basedir.walkBottomUp()) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
|
||||
namesBottomUp.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesBottomUp)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withEnterLeave() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
val namesTopDownEnter = HashSet<String>()
|
||||
val namesTopDownLeave = HashSet<String>()
|
||||
val namesTopDown = HashSet<String>()
|
||||
fun enter(file: File) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDownEnter.contains(name), "$name is entered twice")
|
||||
namesTopDownEnter.add(name)
|
||||
assertFalse(namesTopDownLeave.contains(name), "$name is left before entrance")
|
||||
}
|
||||
fun leave(file: File) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDownLeave.contains(name), "$name is left twice")
|
||||
namesTopDownLeave.add(name)
|
||||
assertTrue(namesTopDownEnter.contains(name), "$name is left before entrance")
|
||||
}
|
||||
fun visit(file: File) {
|
||||
val name = file.relativeTo(basedir)
|
||||
if (file.isDirectory()) {
|
||||
assertTrue(namesTopDownEnter.contains(name), "$name is visited before entrance")
|
||||
namesTopDown.add(name)
|
||||
assertFalse(namesTopDownLeave.contains(name), "$name is visited after leaving")
|
||||
}
|
||||
if (file == basedir)
|
||||
return
|
||||
val parent = file.getParentFile()
|
||||
if (parent != null) {
|
||||
val parentName = parent.relativeTo(basedir)
|
||||
assertTrue(namesTopDownEnter.contains(parentName),
|
||||
"$name is visited before entering its parent $parentName")
|
||||
assertFalse(namesTopDownLeave.contains(parentName),
|
||||
"$name is visited after leaving its parent $parentName")
|
||||
}
|
||||
}
|
||||
for (file in basedir.walkTopDown().enter(::enter).leave(::leave)) {
|
||||
visit(file)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDownEnter)
|
||||
assertEquals(referenceNames, namesTopDownLeave)
|
||||
namesTopDownEnter.clear()
|
||||
namesTopDownLeave.clear()
|
||||
namesTopDown.clear()
|
||||
for (file in basedir.walkBottomUp().enter(::enter).leave(::leave)) {
|
||||
visit(file)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDownEnter)
|
||||
assertEquals(referenceNames, namesTopDownLeave)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withFilterAndMap() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
assertEquals(referenceNames, basedir.walkTopDown().filter{ it.isDirectory() }.map{
|
||||
it.relativeTo(basedir) }.toHashSet())
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
test fun withDeleteTxtTopDown() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
val namesTopDown = HashSet<String>()
|
||||
fun enter(file: File) {
|
||||
assertTrue(file.isDirectory())
|
||||
for (child in file.listFiles()) {
|
||||
if (child.name.endsWith("txt"))
|
||||
child.delete()
|
||||
}
|
||||
}
|
||||
for (file in basedir.walkTopDown().enter(::enter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||
namesTopDown.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDown)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withDeleteTxtBottomUp() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "1/3", "6", "8").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
val namesTopDown = HashSet<String>()
|
||||
fun enter(file: File) {
|
||||
assertTrue(file.isDirectory())
|
||||
for (child in file.listFiles()) {
|
||||
if (child.name.endsWith("txt"))
|
||||
child.delete()
|
||||
}
|
||||
}
|
||||
for (file in basedir.walkBottomUp().enter(::enter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||
namesTopDown.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDown)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withFilter() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
fun filter(file: File): Boolean {
|
||||
// Everything ended with 3 is filtered
|
||||
return (!file.name.endsWith("3"));
|
||||
}
|
||||
val referenceNames =
|
||||
listOf("", "1", "1/2", "6", "7.txt", "8", "8/9.txt").map(
|
||||
{it -> it.separatorsToSystem()}).toHashSet()
|
||||
val namesTopDown = HashSet<String>()
|
||||
for (file in basedir.walkTopDown().filter(::filter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||
namesTopDown.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDown)
|
||||
val namesBottomUp = HashSet<String>()
|
||||
for (file in basedir.walkBottomUp().filter(::filter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
|
||||
namesBottomUp.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesBottomUp)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withTotalFilter() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
// Everything is filtered
|
||||
fun filter(file: File) = false
|
||||
val referenceNames: Set<String> = setOf()
|
||||
val namesTopDown = HashSet<String>()
|
||||
for (file in basedir.walkTopDown().filter(::filter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesTopDown.contains(name), "$name is visited twice")
|
||||
namesTopDown.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesTopDown)
|
||||
val namesBottomUp = HashSet<String>()
|
||||
for (file in basedir.walkBottomUp().filter(::filter)) {
|
||||
val name = file.relativeTo(basedir)
|
||||
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
|
||||
namesBottomUp.add(name)
|
||||
}
|
||||
assertEquals(referenceNames, namesBottomUp)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withForEach() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
var i = 0
|
||||
basedir.walkTopDown().forEach { it -> i++ }
|
||||
assertEquals(10, i);
|
||||
i = 0
|
||||
basedir.walkBottomUp().forEach { it -> i++ }
|
||||
assertEquals(10, i);
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withCount() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
assertEquals(10, basedir.walkTopDown().count());
|
||||
assertEquals(10, basedir.walkBottomUp().count());
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withReduce() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val res = basedir.walkTopDown().reduce { (a, b) -> if (a.canonicalPath > b.canonicalPath) a else b }
|
||||
assertTrue(res.endsWith("9.txt"), "Expected end with 9.txt actual: ${res.name}")
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun withVisitorAndDepth() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val files = HashSet<String>()
|
||||
val dirs = HashSet<String>()
|
||||
val failed = HashSet<String>()
|
||||
val stack = ArrayList<File>()
|
||||
fun beforeVisitDirectory(dir: File) {
|
||||
stack.add(dir)
|
||||
dirs.add(dir.relativeTo(basedir))
|
||||
}
|
||||
fun afterVisitDirectory(dir: File) {
|
||||
assertEquals(stack.last(), dir)
|
||||
stack.remove(stack.lastIndex)
|
||||
}
|
||||
fun visitFile(file: File) {
|
||||
assert(stack.last().listFiles().contains(file), file)
|
||||
files.add(file.relativeTo(basedir))
|
||||
}
|
||||
fun visitDirectoryFailed(dir: File, e: IOException) {
|
||||
assertEquals(stack.last(), dir)
|
||||
stack.remove(stack.lastIndex)
|
||||
failed.add(dir.name)
|
||||
}
|
||||
basedir.walkTopDown().enter(::beforeVisitDirectory).leave(::afterVisitDirectory).
|
||||
fail(::visitDirectoryFailed).forEach{ it -> if (!it.isDirectory()) visitFile(it) }
|
||||
assert(stack.isEmpty())
|
||||
val sep = File.separator
|
||||
for (fileName in array("", "1", "1${sep}2", "1${sep}3", "6", "8")) {
|
||||
assert(dirs.contains(fileName), fileName)
|
||||
}
|
||||
for (fileName in array("1${sep}3${sep}4.txt", "1${sep}3${sep}4.txt", "7.txt", "8${sep}9.txt")) {
|
||||
assert(files.contains(fileName), fileName)
|
||||
}
|
||||
|
||||
//limit maxDepth
|
||||
files.clear()
|
||||
dirs.clear()
|
||||
basedir.walkTopDown().enter(::beforeVisitDirectory).leave(::afterVisitDirectory).maxDepth(1).
|
||||
forEach{ it -> if (it != basedir) visitFile(it) }
|
||||
assert(stack.isEmpty())
|
||||
assert(dirs.size() == 1 && dirs.contains(""), dirs.size())
|
||||
for (file in array("1", "6", "7.txt", "8")) {
|
||||
assert(files.contains(file), file)
|
||||
}
|
||||
|
||||
//restrict access
|
||||
if (File(basedir, "1").setReadable(false)) {
|
||||
try {
|
||||
files.clear()
|
||||
dirs.clear()
|
||||
basedir.walkTopDown().enter(::beforeVisitDirectory).leave(::afterVisitDirectory).
|
||||
fail(::visitDirectoryFailed).forEach{ it -> if (!it.isDirectory()) visitFile(it) }
|
||||
assert(stack.isEmpty())
|
||||
assert(failed.size() == 1 && failed.contains("1"), failed.size())
|
||||
assert(dirs.size() == 4, dirs.size())
|
||||
for (dir in array("", "1", "6", "8")) {
|
||||
assert(dirs.contains(dir), dir)
|
||||
}
|
||||
assert(files.size() == 2, files.size())
|
||||
for (file in array("7.txt", "8${sep}9.txt")) {
|
||||
assert(files.contains(file), file)
|
||||
}
|
||||
} finally {
|
||||
File(basedir, "1").setReadable(true)
|
||||
}
|
||||
} else {
|
||||
System.err.println("cannot restrict access")
|
||||
}
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun topDown() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
val visited = HashSet<File>()
|
||||
val block: (File) -> Unit = {
|
||||
assert(!visited.contains(it), it)
|
||||
assert(it == basedir && visited.isEmpty() || visited.contains(it.getParentFile()), it)
|
||||
visited.add(it)
|
||||
}
|
||||
basedir.walkTopDown().forEach( block )
|
||||
assert(visited.size() == 10, visited.size())
|
||||
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun restrictedAccess() {
|
||||
val basedir = createTestFiles()
|
||||
val restricted = File(basedir, "1")
|
||||
try {
|
||||
if (restricted.setReadable(false)) {
|
||||
val visited = HashSet<File>()
|
||||
val block: (File) -> Unit = {
|
||||
assert(!visited.contains(it), it)
|
||||
assert(it == basedir && visited.isEmpty() || visited.contains(it.getParentFile()), it)
|
||||
visited.add(it)
|
||||
}
|
||||
basedir.walkTopDown().forEach( block )
|
||||
assert(visited.size() == 6, visited.size())
|
||||
}
|
||||
} finally {
|
||||
restricted.setReadable(true)
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun backup() {
|
||||
var count = 0
|
||||
fun makeBackup(file: File) {
|
||||
count++
|
||||
val bakFile = File(file.toString() + ".bak")
|
||||
file.copyTo(bakFile)
|
||||
}
|
||||
|
||||
val basedir1 = createTestFiles()
|
||||
try {
|
||||
basedir1.walkTopDown().forEach {
|
||||
if (it.isFile()) {
|
||||
makeBackup(it)
|
||||
}
|
||||
}
|
||||
assert(count == 4)
|
||||
} finally {
|
||||
basedir1.deleteRecursively()
|
||||
}
|
||||
|
||||
count = 0
|
||||
val basedir2 = createTestFiles()
|
||||
try {
|
||||
basedir2.walkTopDown().forEach {
|
||||
if (it.isFile()) {
|
||||
makeBackup(it)
|
||||
}
|
||||
}
|
||||
assert(count == 4)
|
||||
} finally {
|
||||
basedir2.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun find() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
File(basedir, "8/4.txt".separatorsToSystem()).createNewFile()
|
||||
var count = 0
|
||||
basedir.walkTopDown().takeWhile{ it -> count == 0 }.forEach {
|
||||
if (it.name == "4.txt") {
|
||||
count++
|
||||
}
|
||||
}
|
||||
assert(count == 1)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun findGits() {
|
||||
val basedir = createTestFiles()
|
||||
try {
|
||||
File(basedir, "1/3/.git").mkdir()
|
||||
File(basedir, "1/2/.git").mkdir()
|
||||
File(basedir, "6/.git").mkdir()
|
||||
val found = HashSet<File>()
|
||||
for (file in basedir.walkTopDown()) {
|
||||
if (file.name == ".git") {
|
||||
found.add(file.getParentFile())
|
||||
}
|
||||
}
|
||||
assert(found.size() == 3)
|
||||
} finally {
|
||||
basedir.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
test fun streamFileTree() {
|
||||
val dir = createTempDir()
|
||||
try {
|
||||
val subDir1 = createTempDir(prefix = "d1_", directory = dir)
|
||||
val subDir2 = createTempDir(prefix = "d2_", directory = dir)
|
||||
createTempDir(prefix = "d1_", directory = subDir1)
|
||||
createTempFile(prefix = "f1_", directory = subDir1)
|
||||
createTempDir(prefix = "d1_", directory = subDir2)
|
||||
assertEquals(6, dir.walkTopDown().count())
|
||||
} finally {
|
||||
dir.deleteRecursively()
|
||||
}
|
||||
dir.mkdir()
|
||||
try {
|
||||
val it = dir.walkTopDown().iterator()
|
||||
it.next()
|
||||
it.next()
|
||||
assert(false)
|
||||
} catch(e: NoSuchElementException) {
|
||||
} finally {
|
||||
dir.delete()
|
||||
}
|
||||
try {
|
||||
dir.walkTopDown()
|
||||
assert(false)
|
||||
} catch(e: FileNotFoundException) {}
|
||||
}
|
||||
}
|
||||
|
||||
test fun listFilesWithFilter() {
|
||||
val dir = createTempDir("temp")
|
||||
|
||||
createTempFile("temp1", ".kt", dir)
|
||||
createTempFile("temp2", ".java", dir)
|
||||
createTempFile("temp3", ".kt", dir)
|
||||
|
||||
val result = dir.listFiles { it.getName().endsWith(".kt") }
|
||||
assertEquals(2, result!!.size())
|
||||
}
|
||||
|
||||
test fun recurse() {
|
||||
val dir = File.createTempFile("temp", System.nanoTime().toString())
|
||||
dir.delete()
|
||||
test fun relativeToTest() {
|
||||
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))
|
||||
}
|
||||
|
||||
var totalFiles = 0
|
||||
dir.recurse { totalFiles++ }
|
||||
assertEquals(1, totalFiles)
|
||||
test fun relativeTo() {
|
||||
assertEquals("kotlin", File("src/kotlin".separatorsToSystem()).relativeTo(File("src")))
|
||||
assertEquals("", File("dir").relativeTo(File("dir")))
|
||||
assertEquals("..", File("dir").relativeTo(File("dir/subdir".separatorsToSystem())))
|
||||
assertEquals("../../test".separatorsToSystem(), File("test").relativeTo(File("dir/dir".separatorsToSystem())))
|
||||
|
||||
dir.mkdir()
|
||||
|
||||
File.createTempFile("temp", "1.kt", dir)
|
||||
File.createTempFile("temp", "2.java", dir)
|
||||
|
||||
val subdir = File(dir, "subdir")
|
||||
subdir.mkdir()
|
||||
|
||||
File(subdir, "3.txt").createNewFile()
|
||||
|
||||
totalFiles = 0
|
||||
dir.recurse { totalFiles++ }
|
||||
|
||||
assertEquals(5, totalFiles)
|
||||
|
||||
if (subdir.setReadable(false)) {
|
||||
// On Windows, we can't make directory not readable, and setReadable() will return false
|
||||
|
||||
totalFiles = 0
|
||||
dir.recurse { totalFiles++ }
|
||||
assertEquals(4, totalFiles)
|
||||
// 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 {
|
||||
val winRelPath = file1.relativeTo(file2)
|
||||
assert(file1.canonicalPath.charAt(0) == '/')
|
||||
assertEquals("../../C:/dir1", winRelPath)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
assert(Character.isLetter(file1.canonicalPath.charAt(0)))
|
||||
} catch (e: IOException) {
|
||||
// The device is not ready (D) ==> DO NOTHING
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +589,249 @@ class FilesTest {
|
||||
assertEquals("", file1.relativePath(file1))
|
||||
assertEquals(file3.canonicalPath, file1.relativePath(file3))
|
||||
}
|
||||
|
||||
private fun checkFileElements(f: File, root: File?, elements: List<String>) {
|
||||
var i = 0
|
||||
assertEquals(root, f.root)
|
||||
for (elem in f) {
|
||||
assertTrue(i < elements.size())
|
||||
assertEquals(elements[i++], elem.toString())
|
||||
}
|
||||
assertEquals(elements.size(), i)
|
||||
}
|
||||
|
||||
test fun fileIterator() {
|
||||
checkFileElements(File("/foo/bar"), File("/"), listOf("foo", "bar"))
|
||||
checkFileElements(File("/foo/bar/gav"), File("/"), listOf("foo", "bar", "gav"))
|
||||
checkFileElements(File("/foo/bar/gav/"), File("/"), listOf("foo", "bar", "gav"))
|
||||
checkFileElements(File("bar/gav"), null, listOf("bar", "gav"))
|
||||
checkFileElements(File("C:\\bar\\gav"), File("C:\\"), listOf("bar", "gav"))
|
||||
checkFileElements(File("C:\\"), File("C:\\"), listOf())
|
||||
checkFileElements(File("C:"), File("C:"), listOf())
|
||||
checkFileElements(File("//host.ru/home/mike"), File("//host.ru/home"), listOf("mike"))
|
||||
checkFileElements(File(""), null, listOf(""))
|
||||
checkFileElements(File("."), null, listOf("."))
|
||||
checkFileElements(File(".."), null, listOf(".."))
|
||||
}
|
||||
|
||||
test fun startsWith() {
|
||||
assertTrue(File("C:\\Users\\Me\\Temp\\Game").startsWith("C:\\Users\\Me"))
|
||||
assertFalse(File("C:\\Users\\Me\\Temp\\Game").startsWith("C:\\Users\\He"))
|
||||
assertTrue(File("C:\\Users\\Me").startsWith("C:\\"))
|
||||
}
|
||||
|
||||
test fun endsWith() {
|
||||
assertTrue(File("/foo/bar").endsWith("bar"))
|
||||
assertTrue(File("/foo/bar").endsWith("/bar"))
|
||||
assertTrue(File("/foo/bar/gav/bar").endsWith("/bar"))
|
||||
assertTrue(File("/foo/bar/gav/bar").endsWith("/gav/bar"))
|
||||
assertFalse(File("/foo/bar/gav").endsWith("/bar"))
|
||||
assertFalse(File("foo/bar").endsWith("/bar"))
|
||||
}
|
||||
|
||||
test fun subPath() {
|
||||
assertEquals(File("mike"), File("//my.host.net/home/mike/temp").subPath(0, 1))
|
||||
assertEquals(File("bar/gav"), File("/foo/bar/gav/hi").subPath(1, 3))
|
||||
}
|
||||
|
||||
test fun normalize() {
|
||||
assertEquals(File("/foo/bar/baaz"), File("/foo/./bar/gav/../baaz").normalize())
|
||||
assertEquals(File("../../bar"), File("../foo/../../bar").normalize())
|
||||
assertEquals(File("C:\\windows"), File("C:\\home\\..\\documents\\..\\windows").normalize())
|
||||
assertEquals(File("foo"), File("gav/bar/../../foo").normalize())
|
||||
}
|
||||
|
||||
test fun resolve() {
|
||||
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("C:\\Users\\Me\\Documents\\important.doc"),
|
||||
File("C:\\Users\\Me").resolve("Documents\\important.doc"))
|
||||
}
|
||||
|
||||
test fun resolveSibling() {
|
||||
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("C:\\Users\\Me\\Documents\\important.doc"),
|
||||
File("C:\\Users\\Me\\profile.ini").resolveSibling("Documents\\important.doc"))
|
||||
}
|
||||
|
||||
test fun extension() {
|
||||
assertEquals("bbb", File("aaa.bbb").extension)
|
||||
assertEquals("", File("aaa").extension)
|
||||
assertEquals("", File("aaa.").extension)
|
||||
// maybe we should think that such files have name .bbb and no extension
|
||||
assertEquals("bbb", File(".bbb").extension)
|
||||
assertEquals("", File("/my.dir/log").extension)
|
||||
}
|
||||
|
||||
test fun nameWithoutExtension() {
|
||||
assertEquals("aaa", File("aaa.bbb").nameWithoutExtension)
|
||||
assertEquals("aaa", File("aaa").nameWithoutExtension)
|
||||
assertEquals("aaa", File("aaa.").nameWithoutExtension)
|
||||
assertEquals("", File(".bbb").nameWithoutExtension)
|
||||
assertEquals("log", File("/my.dir/log").nameWithoutExtension)
|
||||
}
|
||||
|
||||
test fun separatorsToSystem() {
|
||||
var path = "/aaa/bbb/ccc"
|
||||
assertEquals(path.replace("/", File.separator), File(path).separatorsToSystem())
|
||||
|
||||
path = "C:\\Program Files\\My Awesome Program"
|
||||
assertEquals(path.replace("\\", File.separator), File(path).separatorsToSystem())
|
||||
|
||||
path = "/Libraries\\Java:/Libraries/Python:/Libraries/Ruby"
|
||||
assertEquals(path.replace(":", File.pathSeparator), path.pathSeparatorsToSystem())
|
||||
|
||||
path = "/Libraries\\Java;/Libraries/Python;/Libraries/Ruby"
|
||||
assertEquals(path.replace(";", File.pathSeparator), path.pathSeparatorsToSystem())
|
||||
|
||||
path = "/Libraries\\Java;/Libraries/Python:\\Libraries/Ruby"
|
||||
assertEquals(path.replace("/", File.separator).replace("\\", File.separator)
|
||||
.replace(":", File.pathSeparator).replace(";", File.pathSeparator), path.allSeparatorsToSystem())
|
||||
|
||||
assertEquals("test", "test".allSeparatorsToSystem())
|
||||
}
|
||||
|
||||
test fun testCopyTo() {
|
||||
val srcFile = createTempFile()
|
||||
val dstFile = createTempFile()
|
||||
srcFile.replaceText("Hello, World!")
|
||||
try {
|
||||
srcFile.copyTo(dstFile)
|
||||
assert(false)
|
||||
} catch (e: FileAlreadyExistsException) {}
|
||||
|
||||
var len = srcFile.copyTo(dstFile, overwrite = true)
|
||||
assertEquals(13L, len)
|
||||
assertEquals(srcFile.readText(), dstFile.readText())
|
||||
|
||||
assert(dstFile.delete())
|
||||
len = srcFile.copyTo(dstFile)
|
||||
assertEquals(13L, len)
|
||||
assertEquals(srcFile.readText(), dstFile.readText())
|
||||
|
||||
assert(dstFile.delete())
|
||||
dstFile.mkdir()
|
||||
val child = File(dstFile, "child")
|
||||
child.createNewFile()
|
||||
srcFile.copyTo(dstFile, overwrite = true)
|
||||
assertEquals(13L, len)
|
||||
val copy = dstFile.resolve(srcFile.name)
|
||||
assertEquals(srcFile.readText(), copy.readText())
|
||||
|
||||
assert(srcFile.delete())
|
||||
assert(child.delete() && copy.delete() && dstFile.delete())
|
||||
|
||||
try {
|
||||
srcFile.copyTo(dstFile)
|
||||
assert(false)
|
||||
} catch (e: NoSuchFileException) {}
|
||||
|
||||
srcFile.mkdir()
|
||||
try {
|
||||
srcFile.copyTo(dstFile)
|
||||
assert(false)
|
||||
} catch (e: IllegalArgumentException) {}
|
||||
srcFile.delete()
|
||||
}
|
||||
|
||||
test fun deleteRecursively() {
|
||||
val dir = createTempDir()
|
||||
dir.delete()
|
||||
dir.mkdir()
|
||||
val subDir = File(dir, "subdir");
|
||||
subDir.mkdir()
|
||||
File(dir, "test1.txt").createNewFile()
|
||||
File(subDir, "test2.txt").createNewFile()
|
||||
|
||||
assert(dir.deleteRecursively())
|
||||
assert(!dir.exists())
|
||||
assert(!dir.deleteRecursively())
|
||||
}
|
||||
|
||||
test fun copyRecursively() {
|
||||
val src = createTempDir()
|
||||
val dst = createTempDir()
|
||||
dst.delete()
|
||||
fun check() {
|
||||
for (file in src.walkTopDown()) {
|
||||
val dstFile = File(dst, file.relativeTo(src))
|
||||
assert(dstFile.exists())
|
||||
if (dstFile.isFile()) {
|
||||
assertEquals(file.readText(), dstFile.readText())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val subDir1 = createTempDir(prefix = "d1_", directory = src)
|
||||
val subDir2 = createTempDir(prefix = "d2_", directory = src)
|
||||
createTempDir(prefix = "d1_", directory = subDir1)
|
||||
val file1 = createTempFile(prefix = "f1_", directory = src)
|
||||
val file2 = createTempFile(prefix = "f2_", directory = subDir1)
|
||||
file1.replaceText("hello")
|
||||
file2.replaceText("wazzup")
|
||||
createTempDir(prefix = "d1_", directory = subDir2)
|
||||
|
||||
assert(src.copyRecursively(dst))
|
||||
check()
|
||||
|
||||
try {
|
||||
src.copyRecursively(dst)
|
||||
assert(false)
|
||||
} catch (e: FileAlreadyExistsException) {
|
||||
}
|
||||
|
||||
var conflicts = 0
|
||||
src.copyRecursively(dst) {
|
||||
(file: File, e: IOException) ->
|
||||
if (e is FileAlreadyExistsException) {
|
||||
conflicts++
|
||||
OnErrorAction.SKIP
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
assert(conflicts == 2)
|
||||
|
||||
if (subDir1.setReadable(false)) {
|
||||
try {
|
||||
dst.deleteRecursively()
|
||||
var caught = false
|
||||
assert(src.copyRecursively(dst) {
|
||||
(file: File, e: IOException) ->
|
||||
if (e is AccessDeniedException) {
|
||||
caught = true
|
||||
OnErrorAction.SKIP
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
})
|
||||
assert(caught)
|
||||
check()
|
||||
} finally {
|
||||
subDir1.setReadable(true)
|
||||
}
|
||||
}
|
||||
|
||||
src.deleteRecursively()
|
||||
dst.deleteRecursively()
|
||||
try {
|
||||
src.copyRecursively(dst)
|
||||
assert(false)
|
||||
} catch (e: NoSuchFileException) {
|
||||
}
|
||||
|
||||
assert(!src.copyRecursively(dst) {
|
||||
(file: File, e: IOException) ->
|
||||
OnErrorAction.TERMINATE
|
||||
})
|
||||
} finally {
|
||||
src.deleteRecursively()
|
||||
dst.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package test.io
|
||||
|
||||
import org.junit.Test as test
|
||||
import java.io.Writer
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import kotlinhack.test.assertEquals
|
||||
|
||||
class IOStreamsTest {
|
||||
test fun testGetStreamOfFile() {
|
||||
val tmpFile = createTempFile()
|
||||
var writer: Writer? = null
|
||||
try {
|
||||
writer = tmpFile.outputStream().writer()
|
||||
writer!!.write("Hello, World!")
|
||||
} finally {
|
||||
writer?.close()
|
||||
}
|
||||
var act: String?
|
||||
var reader: BufferedReader? = null
|
||||
try {
|
||||
reader = tmpFile.inputStream().reader().buffered()
|
||||
act = reader!!.readLine()
|
||||
} finally {
|
||||
reader?.close()
|
||||
}
|
||||
assertEquals("Hello, World!", act)
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,17 @@ import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
import java.io.Reader
|
||||
import java.io.StringReader
|
||||
import java.net.URL
|
||||
import java.util.ArrayList
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
fun sample(): Reader = StringReader("Hello\nWorld");
|
||||
|
||||
class ReadWriteTest {
|
||||
test fun testAppendText() {
|
||||
val file = File.createTempFile("temp", System.nanoTime().toString())
|
||||
file.writeText("Hello\n")
|
||||
file.replaceText("Hello\n")
|
||||
file.appendText("World")
|
||||
|
||||
assertEquals("Hello\nWorld", file.readText())
|
||||
@@ -60,29 +63,42 @@ class ReadWriteTest {
|
||||
|
||||
test fun file() {
|
||||
val file = File.createTempFile("temp", System.nanoTime().toString())
|
||||
val writer = file.outputStream().writer().buffered()
|
||||
|
||||
file.writeText("Hello\nWorld")
|
||||
writer.write("Hello")
|
||||
writer.newLine()
|
||||
writer.write("World")
|
||||
writer.close()
|
||||
|
||||
//file.replaceText("Hello\nWorld")
|
||||
file.forEachBlock{ (arr: ByteArray, size: Int) ->
|
||||
assertTrue(size >= 11 && size <= 12, size.toString())
|
||||
assertTrue(arr.contains('W'.toByte()))
|
||||
}
|
||||
val list = ArrayList<String>()
|
||||
file.forEachLine{
|
||||
list.add(it)
|
||||
}
|
||||
assertEquals(arrayListOf("Hello", "World"), list)
|
||||
val text = file.inputStream().reader().readText()
|
||||
assertTrue(text.contains("Hello"))
|
||||
assertTrue(text.contains("World"))
|
||||
|
||||
file.writeText("")
|
||||
file.replaceText("")
|
||||
var c = 0
|
||||
file.forEachLine { c++ }
|
||||
assertEquals(0, c)
|
||||
|
||||
file.writeText(" ")
|
||||
file.replaceText(" ")
|
||||
file.forEachLine { c++ }
|
||||
assertEquals(1, c)
|
||||
|
||||
file.writeText(" \n")
|
||||
file.replaceText(" \n")
|
||||
c = 0
|
||||
file.forEachLine { c++ }
|
||||
assertEquals(1, c)
|
||||
|
||||
file.writeText(" \n ")
|
||||
file.replaceText(" \n ")
|
||||
c = 0
|
||||
file.forEachLine { c++ }
|
||||
assertEquals(2, c)
|
||||
@@ -146,4 +162,10 @@ class ReadWriteTest {
|
||||
|
||||
assertEquals(arrayListOf("Hello", "World"), list)
|
||||
}
|
||||
|
||||
test fun testURL() {
|
||||
val url = URL("http://kotlinlang.org")
|
||||
val text = url.readText()
|
||||
assertFalse(text.isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user