diff --git a/libraries/stdlib/test/io/FileTreeWalks.kt b/libraries/stdlib/test/io/FileTreeWalks.kt new file mode 100644 index 00000000000..02f44306769 --- /dev/null +++ b/libraries/stdlib/test/io/FileTreeWalks.kt @@ -0,0 +1,471 @@ +package test.io + +import org.junit.Test +import java.io.File +import java.io.IOException +import java.util.* +import kotlin.test.* + +class FileTreeWalkTest { + + companion object { + 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() + 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() + 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() + val namesTopDownLeave = HashSet() + val namesTopDown = HashSet() + 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() + 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() + 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() + 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() + 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 { + val referenceNames: Set = setOf() + val namesTopDown = HashSet() + // Everything is filtered + for (file in basedir.walkTopDown().filter({ false })) { + val name = file.relativeTo(basedir) + assertFalse(namesTopDown.contains(name), "$name is visited twice") + namesTopDown.add(name) + } + assertEquals(referenceNames, namesTopDown) + val namesBottomUp = HashSet() + // Everything is filtered + for (file in basedir.walkBottomUp().filter({ false })) { + 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() + val dirs = HashSet() + val failed = HashSet() + val stack = ArrayList() + fun beforeVisitDirectory(dir: File) { + stack.add(dir) + dirs.add(dir.relativeTo(basedir)) + } + + fun afterVisitDirectory(dir: File) { + assertEquals(stack.last(), dir) + stack.removeAt(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.removeAt(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 arrayOf("", "1", "1${sep}2", "1${sep}3", "6", "8")) { + 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")) { + 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 arrayOf("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 arrayOf("", "1", "6", "8")) { + assert(dirs.contains(dir)) { dir } + } + assert(files.size == 2) { files.size } + for (file in arrayOf("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() + 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() + 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() + 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() + } + } + +} diff --git a/libraries/stdlib/test/io/Files.kt b/libraries/stdlib/test/io/Files.kt index 46570f4548a..d38e1f5d1bf 100644 --- a/libraries/stdlib/test/io/Files.kt +++ b/libraries/stdlib/test/io/Files.kt @@ -3,10 +3,6 @@ package test.io import java.io.* import org.junit.Test as test import kotlin.test.assertEquals -import java.util.NoSuchElementException -import java.util.HashSet -import java.util.ArrayList -import kotlin.io.walkBottomUp import kotlin.io.walkTopDown import kotlin.test.* @@ -59,470 +55,6 @@ class FilesTest { file3.delete() } - class Walks { - - companion object { - 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() - 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() - 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() - val namesTopDownLeave = HashSet() - val namesTopDown = HashSet() - 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() - 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() - 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() - 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() - 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 { - val referenceNames: Set = setOf() - val namesTopDown = HashSet() - // Everything is filtered - for (file in basedir.walkTopDown().filter({ false })) { - val name = file.relativeTo(basedir) - assertFalse(namesTopDown.contains(name), "$name is visited twice") - namesTopDown.add(name) - } - assertEquals(referenceNames, namesTopDown) - val namesBottomUp = HashSet() - // Everything is filtered - for (file in basedir.walkBottomUp().filter({ false })) { - 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() - val dirs = HashSet() - val failed = HashSet() - val stack = ArrayList() - fun beforeVisitDirectory(dir: File) { - stack.add(dir) - dirs.add(dir.relativeTo(basedir)) - } - - fun afterVisitDirectory(dir: File) { - assertEquals(stack.last(), dir) - stack.removeAt(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.removeAt(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 arrayOf("", "1", "1${sep}2", "1${sep}3", "6", "8")) { - 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")) { - 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 arrayOf("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 arrayOf("", "1", "6", "8")) { - assert(dirs.contains(dir)) { dir } - } - assert(files.size == 2) { files.size } - for (file in arrayOf("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() - 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() - 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() - 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() - } - } - - } - @test fun listFilesWithFilter() { val dir = createTempDir("temp") @@ -795,9 +327,9 @@ class FilesTest { assert(!dir.exists()) assert(!dir.deleteRecursively()) } - + @test fun deleteRecursivelyWithFail() { - val basedir = Walks.createTestFiles() + val basedir = FileTreeWalkTest.createTestFiles() val restricted = File(basedir, "1") try { if (restricted.setReadable(false)) { diff --git a/libraries/stdlib/test/io/ReadWrite.kt b/libraries/stdlib/test/io/ReadWrite.kt index aa0eb7f669e..a832d13e0a3 100644 --- a/libraries/stdlib/test/io/ReadWrite.kt +++ b/libraries/stdlib/test/io/ReadWrite.kt @@ -108,45 +108,7 @@ class ReadWriteTest { file.deleteOnExit() } - class LineIteratorTest { - @test fun useLines() { - // TODO we should maybe zap the useLines approach as it encourages - // use of iterators which don't close the underlying stream - val list1 = sample().useLines { it.toArrayList() } - val list2 = sample().useLines>{ it.toArrayList() } - assertEquals(arrayListOf("Hello", "World"), list1) - assertEquals(arrayListOf("Hello", "World"), list2) - } - - @test fun manualClose() { - val reader = sample().buffered() - try { - val list = reader.lineSequence().toArrayList() - assertEquals(arrayListOf("Hello", "World"), list) - } finally { - reader.close() - } - } - - @test fun boundaryConditions() { - var reader = StringReader("").buffered() - assertEquals(ArrayList(), reader.lineSequence().toArrayList()) - reader.close() - - reader = StringReader(" ").buffered() - assertEquals(arrayListOf(" "), reader.lineSequence().toArrayList()) - reader.close() - - reader = StringReader(" \n").buffered() - assertEquals(arrayListOf(" "), reader.lineSequence().toArrayList()) - reader.close() - - reader = StringReader(" \n ").buffered() - assertEquals(arrayListOf(" ", " "), reader.lineSequence().toArrayList()) - reader.close() - } - } @test fun testUse() { val list = ArrayList() @@ -173,3 +135,44 @@ class ReadWriteTest { assertFalse(text2.isEmpty()) } } + + +class LineIteratorTest { + @test fun useLines() { + // TODO we should maybe zap the useLines approach as it encourages + // use of iterators which don't close the underlying stream + val list1 = sample().useLines { it.toArrayList() } + val list2 = sample().useLines>{ it.toArrayList() } + + assertEquals(arrayListOf("Hello", "World"), list1) + assertEquals(arrayListOf("Hello", "World"), list2) + } + + @test fun manualClose() { + val reader = sample().buffered() + try { + val list = reader.lineSequence().toArrayList() + assertEquals(arrayListOf("Hello", "World"), list) + } finally { + reader.close() + } + } + + @test fun boundaryConditions() { + var reader = StringReader("").buffered() + assertEquals(ArrayList(), reader.lineSequence().toArrayList()) + reader.close() + + reader = StringReader(" ").buffered() + assertEquals(arrayListOf(" "), reader.lineSequence().toArrayList()) + reader.close() + + reader = StringReader(" \n").buffered() + assertEquals(arrayListOf(" "), reader.lineSequence().toArrayList()) + reader.close() + + reader = StringReader(" \n ").buffered() + assertEquals(arrayListOf(" ", " "), reader.lineSequence().toArrayList()) + reader.close() + } +}