stdlib tests: move JVM-only test source files

This commit is contained in:
Ilya Gorbunov
2018-01-25 23:28:32 +03:00
parent ba873e2b46
commit 9b38e5e7b5
32 changed files with 0 additions and 17 deletions
+90
View File
@@ -0,0 +1,90 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@file:kotlin.jvm.JvmVersion
package test.io
import org.junit.Test
import java.nio.charset.Charset
import kotlin.test.*
class ConsoleTest {
private val linuxLineSeparator: String = "\n"
private val windowsLineSeparator: String = "\r\n"
@Test
fun shouldReadEmptyLine() {
testReadLine("", emptyList())
}
@Test
fun shouldReadSingleLine() {
for (length in 1..3) {
val line = buildString { repeat(length) { append('a' + it) } }
testReadLine(line, listOf(line))
}
}
@Test
fun trailingEmptyLineIsIgnored() {
testReadLine(linuxLineSeparator, listOf(""))
testReadLine(windowsLineSeparator, listOf(""))
testReadLine("a$linuxLineSeparator", listOf("a"))
testReadLine("a$windowsLineSeparator", listOf("a"))
}
@Test
fun shouldReadOneLine() {
testReadLine("first", listOf("first"))
}
@Test
fun shouldReadTwoLines() {
testReadLine("first${linuxLineSeparator}second", listOf("first", "second"))
}
@Test
fun shouldReadConsecutiveEmptyLines() {
testReadLine("$linuxLineSeparator$linuxLineSeparator", listOf("", ""))
testReadLine("$linuxLineSeparator$windowsLineSeparator", listOf("", ""))
testReadLine("$windowsLineSeparator$linuxLineSeparator", listOf("", ""))
testReadLine("$windowsLineSeparator$windowsLineSeparator", listOf("", ""))
}
@Test
fun shouldReadWindowsLineSeparator() {
testReadLine("first${windowsLineSeparator}second", listOf("first", "second"))
}
@Test
fun shouldReadMultibyteEncodings() {
testReadLine("first${linuxLineSeparator}second", listOf("first", "second"), charset = Charsets.UTF_32)
}
private fun testReadLine(text: String, expected: List<String>, charset: Charset = Charsets.UTF_8) {
val actual = readLines(text, charset)
assertEquals(expected, actual)
val referenceExpected = readLinesReference(text, charset)
assertEquals(referenceExpected, actual, "Comparing to reference readLine")
}
private fun readLines(text: String, charset: Charset): List<String> {
text.byteInputStream(charset).use { stream ->
val decoder = charset.newDecoder()
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
return generateSequence { readLine(stream, decoder) }.toList().also {
assertTrue("All bytes should be read") { stream.read() == -1 }
}
}
}
private fun readLinesReference(text: String, charset: Charset): List<String> {
text.byteInputStream(charset).bufferedReader(charset).use { reader ->
return generateSequence { reader.readLine() }.toList()
}
}
}
@@ -0,0 +1,458 @@
@file:kotlin.jvm.JvmVersion
package test.io
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.test.*
class FileTreeWalkTest {
companion object {
val referenceFilenames =
listOf("1", "1/2", "1/3", "1/3/4.txt", "1/3/5.txt", "6", "7.txt", "8", "8/9.txt")
fun createTestFiles(): File {
val basedir = createTempDir()
for (name in referenceFilenames) {
val file = basedir.resolve(name)
if (file.extension.isEmpty())
file.mkdir()
else
file.createNewFile()
}
return basedir
}
}
@Test fun withSimple() {
val basedir = createTestFiles()
try {
val referenceNames = setOf("") + referenceFilenames
val namesTopDown = HashSet<String>()
for (file in basedir.walkTopDown()) {
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
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.relativeToOrSelf(basedir).invariantSeparatorsPath
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
namesBottomUp.add(name)
}
assertEquals(referenceNames, namesBottomUp)
} finally {
basedir.deleteRecursively()
}
}
@Test fun singleFile() {
val testFile = createTempFile()
val nonExistantFile = testFile.resolve("foo")
try {
for (walk in listOf(File::walkTopDown, File::walkBottomUp)) {
assertEquals(testFile, walk(testFile).single(), "${walk.name}")
assertEquals(testFile, testFile.walk().onEnter { false }.single(), "${walk.name} - enter should not be called for single file")
assertTrue(walk(nonExistantFile).none(), "${walk.name} - enter should not be called for single file")
}
}
finally {
testFile.delete()
}
}
@Test fun withEnterLeave() {
val basedir = createTestFiles()
try {
val referenceNames =
setOf("", "1", "1/2", "6", "8")
val namesTopDownEnter = HashSet<String>()
val namesTopDownLeave = HashSet<String>()
val namesTopDown = HashSet<String>()
fun enter(file: File): Boolean {
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
assertTrue(file.isDirectory, "$name is not directory, only directories should be entered")
assertFalse(namesTopDownEnter.contains(name), "$name is entered twice")
assertFalse(namesTopDownLeave.contains(name), "$name is left before entrance")
if (file.name == "3") return false // filter out 3
namesTopDownEnter.add(name)
return true
}
fun leave(file: File) {
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
assertTrue(file.isDirectory, "$name is not directory, only directories should be left")
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.relativeToOrSelf(basedir).invariantSeparatorsPath
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.parentFile
if (parent != null) {
val parentName = parent.relativeToOrSelf(basedir).invariantSeparatorsPath
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().onEnter(::enter).onLeave(::leave)) {
visit(file)
}
assertEquals(referenceNames, namesTopDownEnter)
assertEquals(referenceNames, namesTopDownLeave)
namesTopDownEnter.clear()
namesTopDownLeave.clear()
namesTopDown.clear()
for (file in basedir.walkBottomUp().onEnter(::enter).onLeave(::leave)) {
visit(file)
}
assertEquals(referenceNames, namesTopDownEnter)
assertEquals(referenceNames, namesTopDownLeave)
} finally {
basedir.deleteRecursively()
}
}
@Test fun withFilterAndMap() {
val basedir = createTestFiles()
try {
val referenceNames = setOf("", "1", "1/2", "1/3", "6", "8")
assertEquals(referenceNames, basedir.walkTopDown().filter { it.isDirectory }.map {
it.relativeToOrSelf(basedir).invariantSeparatorsPath
}.toHashSet())
} finally {
basedir.deleteRecursively()
}
}
@Test fun withDeleteTxtTopDown() {
val basedir = createTestFiles()
try {
val referenceNames = setOf("", "1", "1/2", "1/3", "6", "8")
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().onEnter { enter(it); true }) {
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
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 = setOf("", "1", "1/2", "1/3", "6", "8")
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().onEnter { enter(it); true }) {
val name = file.relativeToOrSelf(basedir).invariantSeparatorsPath
assertFalse(namesTopDown.contains(name), "$name is visited twice")
namesTopDown.add(name)
}
assertEquals(referenceNames, namesTopDown)
} finally {
basedir.deleteRecursively()
}
}
private fun compareWalkResults(expected: Set<String>, basedir: File, filter: (File) -> Boolean) {
val namesTopDown = HashSet<String>()
for (file in basedir.walkTopDown().onEnter { filter(it) }) {
val name = file.toRelativeString(basedir)
assertFalse(namesTopDown.contains(name), "$name is visited twice")
namesTopDown.add(name)
}
assertEquals(expected, namesTopDown, "Top-down walk results differ")
val namesBottomUp = HashSet<String>()
for (file in basedir.walkBottomUp().onEnter { filter(it) }) {
val name = file.toRelativeString(basedir)
assertFalse(namesBottomUp.contains(name), "$name is visited twice")
namesBottomUp.add(name)
}
assertEquals(expected, namesBottomUp, "Bottom-up walk results differ")
}
@Test fun withDirectoryFilter() {
val basedir = createTestFiles()
try {
// Every directory ended with 3 and its content is filtered out
fun filter(file: File): Boolean = !file.name.endsWith("3")
val referenceNames = listOf("", "1", "1/2", "6", "7.txt", "8", "8/9.txt").map { File(it).path }.toSet()
compareWalkResults(referenceNames, basedir, ::filter)
} finally {
basedir.deleteRecursively()
}
}
@Test fun withTotalDirectoryFilter() {
val basedir = createTestFiles()
try {
val referenceNames = emptySet<String>()
compareWalkResults(referenceNames, basedir, { false })
} finally {
basedir.deleteRecursively()
}
}
@Test fun withForEach() {
val basedir = createTestFiles()
try {
var i = 0
basedir.walkTopDown().forEach { _ -> i++ }
assertEquals(10, i);
i = 0
basedir.walkBottomUp().forEach { _ -> 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<File>()
val dirs = HashSet<File>()
val failed = HashSet<String>()
val stack = ArrayList<File>()
fun beforeVisitDirectory(dir: File): Boolean {
stack.add(dir)
dirs.add(dir.relativeToOrSelf(basedir))
return true
}
fun afterVisitDirectory(dir: File) {
assertEquals(stack.last(), dir)
stack.removeAt(stack.lastIndex)
}
fun visitFile(file: File) {
assertTrue(stack.last().listFiles().contains(file), file.toString())
files.add(file.relativeToOrSelf(basedir))
}
fun visitDirectoryFailed(dir: File, @Suppress("UNUSED_PARAMETER") e: IOException) {
assertEquals(stack.last(), dir)
//stack.removeAt(stack.lastIndex)
failed.add(dir.name)
}
basedir.walkTopDown().onEnter(::beforeVisitDirectory).onLeave(::afterVisitDirectory).
onFail(::visitDirectoryFailed).forEach { it -> if (!it.isDirectory) visitFile(it) }
assertTrue(stack.isEmpty())
for (fileName in arrayOf("", "1", "1/2", "1/3", "6", "8")) {
assertTrue(dirs.contains(File(fileName)), fileName)
}
for (fileName in arrayOf("1/3/4.txt", "1/3/4.txt", "7.txt", "8/9.txt")) {
assertTrue(files.contains(File(fileName)), fileName)
}
//limit maxDepth
files.clear()
dirs.clear()
basedir.walkTopDown().onEnter(::beforeVisitDirectory).onLeave(::afterVisitDirectory).maxDepth(1).
forEach { it -> if (it != basedir) visitFile(it) }
assertTrue(stack.isEmpty())
assertEquals(setOf(File("")), dirs)
for (file in arrayOf("1", "6", "7.txt", "8")) {
assertTrue(files.contains(File(file)), file.toString())
}
//restrict access
if (File(basedir, "1").setReadable(false)) {
try {
files.clear()
dirs.clear()
basedir.walkTopDown().onEnter(::beforeVisitDirectory).onLeave(::afterVisitDirectory).
onFail(::visitDirectoryFailed).forEach { it -> if (!it.isDirectory) visitFile(it) }
assertTrue(stack.isEmpty())
assertEquals(setOf("1"), failed)
assertEquals(listOf("", "1", "6", "8").map { File(it) }.toSet(), dirs)
assertEquals(listOf("7.txt", "8/9.txt").map { File(it) }.toSet(), files)
} 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 = {
assertTrue(!visited.contains(it), it.toString())
assertTrue(it == basedir && visited.isEmpty() || visited.contains(it.parentFile), it.toString())
visited.add(it)
}
basedir.walkTopDown().forEach(block)
assertEquals(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 = {
assertTrue(!visited.contains(it), it.toString())
assertTrue(it == basedir && visited.isEmpty() || visited.contains(it.parentFile), it.toString())
visited.add(it)
}
basedir.walkTopDown().forEach(block)
assertEquals(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)
}
}
assertEquals(4, count)
} finally {
basedir1.deleteRecursively()
}
count = 0
val basedir2 = createTestFiles()
try {
basedir2.walkTopDown().forEach {
if (it.isFile) {
makeBackup(it)
}
}
assertEquals(4, count)
} finally {
basedir2.deleteRecursively()
}
}
@Test fun find() {
val basedir = createTestFiles()
try {
File(basedir, "8/4.txt").createNewFile()
var count = 0
basedir.walkTopDown().takeWhile { _ -> count == 0 }.forEach {
if (it.name == "4.txt") {
count++
}
}
assertEquals(1, count)
} 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.parentFile)
}
}
assertEquals(3, found.size)
} 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()
assertFailsWith<NoSuchElementException>("Second call to next() should fail.") { it.next() }
} finally {
dir.delete()
}
}
}
+621
View File
@@ -0,0 +1,621 @@
@file:kotlin.jvm.JvmVersion
package test.io
import java.io.*
import java.util.*
import kotlin.io.walkTopDown
import kotlin.test.*
class FilesTest {
private val isCaseInsensitiveFileSystem = File("C:/") == File("c:/")
private val isBackslashSeparator = File.separatorChar == '\\'
@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)
assertTrue(dir1.exists() && dir1.isDirectory && dir1.name.startsWith("temp") && dir1.name.endsWith(dirSuf))
assertFailsWith(IllegalArgumentException::class) {
createTempDir("a")
}
val dir2 = createTempDir("temp")
assertTrue(dir2.exists() && dir2.isDirectory && dir2.name.endsWith(".tmp"))
val dir3 = createTempDir()
assertTrue(dir3.exists() && dir3.isDirectory)
dir1.delete()
dir2.delete()
dir3.delete()
}
@Test fun testCreateTempFile() {
val fileSuf = System.currentTimeMillis().toString()
val file1 = createTempFile("temp", fileSuf)
assertTrue(file1.exists() && file1.name.startsWith("temp") && file1.name.endsWith(fileSuf))
assertFailsWith(IllegalArgumentException::class) {
createTempFile("a")
}
val file2 = createTempFile("temp")
assertTrue(file2.exists() && file2.name.endsWith(".tmp"))
val file3 = createTempFile()
assertTrue(file3.exists())
file1.delete()
file2.delete()
file3.delete()
}
@Test fun listFilesWithFilter() {
val dir = createTempDir("temp")
createTempFile("temp1", ".kt", dir)
createTempFile("temp2", ".java", dir)
createTempFile("temp3", ".kt", dir)
// This line works only with Kotlin File.listFiles(filter)
val result = dir.listFiles { it -> it.name.endsWith(".kt") } // todo ambiguity on SAM
assertEquals(2, result!!.size)
// This line works both with Kotlin File.listFiles(filter) and the same Java function because of SAM
val result2 = dir.listFiles { it -> it.name.endsWith(".kt") }
assertEquals(2, result2!!.size)
}
@Test fun relativeToRooted() {
val file1 = File("/foo/bar/baz")
val file2 = File("/foo/baa/ghoo")
assertEquals("../../bar/baz", file1.relativeTo(file2).invariantSeparatorsPath)
val file3 = File("/foo/bar")
assertEquals("baz", file1.toRelativeString(file3))
assertEquals("..", file3.toRelativeString(file1))
val file4 = File("/foo/bar/")
assertEquals("baz", file1.toRelativeString(file4))
assertEquals("..", file4.toRelativeString(file1))
assertEquals("", file3.toRelativeString(file4))
assertEquals("", file4.toRelativeString(file3))
val file5 = File("/foo/baran")
assertEquals("../bar", file3.relativeTo(file5).invariantSeparatorsPath)
assertEquals("../baran", file5.relativeTo(file3).invariantSeparatorsPath)
assertEquals("../bar", file4.relativeTo(file5).invariantSeparatorsPath)
assertEquals("../baran", file5.relativeTo(file4).invariantSeparatorsPath)
if (isBackslashSeparator) {
val file6 = File("C:\\Users\\Me")
val file7 = File("C:\\Users\\Me\\Documents")
assertEquals("..", file6.toRelativeString(file7))
assertEquals("Documents", file7.toRelativeString(file6))
val file8 = File("""\\my.host\home/user/documents/vip""")
val file9 = File("""\\my.host\home/other/images/nice""")
assertEquals("../../../user/documents/vip", file8.relativeTo(file9).invariantSeparatorsPath)
assertEquals("../../../other/images/nice", file9.relativeTo(file8).invariantSeparatorsPath)
}
if (isCaseInsensitiveFileSystem) {
assertEquals("bar", File("C:/bar").toRelativeString(File("c:/")))
}
}
@Test fun relativeToRelative() {
val nested = File("foo/bar")
val base = File("foo")
assertEquals("bar", nested.toRelativeString(base))
assertEquals("..", base.toRelativeString(nested))
val empty = File("")
val current = File(".")
val parent = File("..")
val outOfRoot = File("../bar")
assertEquals(File("../bar"), outOfRoot.relativeTo(empty))
assertEquals(File("../../bar"), outOfRoot.relativeTo(base))
assertEquals("bar", outOfRoot.toRelativeString(parent))
assertEquals("..", parent.toRelativeString(outOfRoot))
val root = File("/root")
val files = listOf(nested, base, empty, outOfRoot, current, parent)
val bases = listOf(nested, base, empty, current)
for (file in files)
assertEquals("", file.toRelativeString(file), "file should have empty path relative to itself: $file")
for (file in files) {
@Suppress("NAME_SHADOWING")
for (base in bases) {
val rootedFile = root.resolve(file)
val rootedBase = root.resolve(base)
assertEquals(file.relativeTo(base), rootedFile.relativeTo(rootedBase), "nested: $file, base: $base")
assertEquals(file.toRelativeString(base), rootedFile.toRelativeString(rootedBase), "strings, nested: $file, base: $base")
}
}
}
@Test fun relativeToFails() {
val absolute = File("/foo/bar/baz")
val relative = File("foo/bar")
val networkShare1 = File("""\\my.host\share1/folder""")
val networkShare2 = File("""\\my.host\share2\folder""")
fun assertFailsRelativeTo(file: File, base: File) {
val e = assertFailsWith<IllegalArgumentException>("file: $file, base: $base") { file.relativeTo(base) }
val message = assertNotNull(e.message)
assert(file.toString() in message)
assert(base.toString() in message)
}
val allFiles = listOf(absolute, relative) + if (isBackslashSeparator) listOf(networkShare1, networkShare2) else emptyList()
for (file in allFiles) {
for (base in allFiles) {
if (file != base) assertFailsRelativeTo(file, base)
}
}
assertFailsRelativeTo(File("y"), File("../x"))
if (isBackslashSeparator) {
val fileOnC = File("C:/dir1")
val fileOnD = File("D:/dir2")
assertFailsRelativeTo(fileOnC, fileOnD)
}
}
@Test fun relativeTo() {
assertEquals("kotlin", File("src/kotlin").toRelativeString(File("src")))
assertEquals("", File("dir").toRelativeString(File("dir")))
assertEquals("..", File("dir").toRelativeString(File("dir/subdir")))
assertEquals(File("../../test"), File("test").relativeTo(File("dir/dir")))
}
@Suppress("INVISIBLE_MEMBER")
private fun checkFilePathComponents(f: File, root: File, elements: List<String>) {
assertEquals(root, f.root)
val components = f.toComponents()
assertEquals(root, components.root)
assertEquals(elements, components.segments.map { it.toString() })
}
@Test fun filePathComponents() {
checkFilePathComponents(File("/foo/bar"), File("/"), listOf("foo", "bar"))
checkFilePathComponents(File("/foo/bar/gav"), File("/"), listOf("foo", "bar", "gav"))
checkFilePathComponents(File("/foo/bar/gav/"), File("/"), listOf("foo", "bar", "gav"))
checkFilePathComponents(File("bar/gav"), File(""), listOf("bar", "gav"))
checkFilePathComponents(File("C:/bar/gav"), File("C:/"), listOf("bar", "gav"))
checkFilePathComponents(File("C:/"), File("C:/"), listOf())
checkFilePathComponents(File("C:"), File("C:"), listOf())
if (isBackslashSeparator) {
// Check only in Windows
checkFilePathComponents(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())
}
checkFilePathComponents(File(""), File(""), listOf())
checkFilePathComponents(File("."), File(""), listOf("."))
checkFilePathComponents(File(".."), File(""), listOf(".."))
}
@Test fun fileRoot() {
val rooted = File("/foo/bar")
assertTrue(rooted.isRooted)
// assertEquals("/", rooted.root.invariantSeparatorsPath)
if (isBackslashSeparator) {
val diskRooted = File("""C:\foo\bar""")
assertTrue(diskRooted.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() {
assertTrue(File("foo/bar").startsWith(File("foo/bar")))
assertTrue(File("foo/bar").startsWith(File("foo")))
assertTrue(File("foo/bar").startsWith(""))
assertFalse(File("foo/bar").startsWith(File("/")))
assertFalse(File("foo/bar").startsWith(File("/foo")))
assertFalse(File("foo/bar").startsWith("fo"))
assertTrue(File("/foo/bar").startsWith(File("/foo/bar")))
assertTrue(File("/foo/bar").startsWith(File("/foo")))
assertTrue(File("/foo/bar").startsWith("/"))
assertFalse(File("/foo/bar").startsWith(""))
assertFalse(File("/foo/bar").startsWith(File("foo")))
assertFalse(File("/foo/bar").startsWith("/fo"))
if (isBackslashSeparator) {
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:\\"))
}
if (isCaseInsensitiveFileSystem) {
assertTrue(File("C:\\Users\\Me").startsWith("c:\\"))
}
}
@Test fun endsWith() {
assertTrue(File("/foo/bar").endsWith("bar"))
assertTrue(File("/foo/bar").endsWith("foo/bar"))
assertTrue(File("/foo/bar").endsWith("/foo/bar"))
assertTrue(File("foo/bar").endsWith("foo/bar"))
assertTrue(File("foo/bar").endsWith("bar/"))
assertFalse(File("/foo/bar").endsWith("ar"))
assertFalse(File("/foo/bar").endsWith("/bar"))
assertFalse(File("/foo/bar/gav/bar").endsWith("/bar"))
assertFalse(File("/foo/bar/gav/bar").endsWith("/gav/bar"))
assertFalse(File("/foo/bar/gav").endsWith("/bar"))
assertFalse(File("foo/bar").endsWith("/bar"))
if (isCaseInsensitiveFileSystem) {
assertTrue(File("/foo/bar").endsWith("Bar"))
}
}
/*
@Test fun subPath() {
if (isBackslashSeparator) {
// Check only in Windows
assertEquals(File("mike"), File("//my.host.net/home/mike/temp").subPath(0, 1))
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))
assertEquals(File("foo"), File("/foo/bar/gav/hi").subPath(0, 1))
assertEquals(File("gav/hi"), File("/foo/bar/gav/hi").subPath(2, 4))
}
*/
@Test fun normalize() {
assertEquals(File("/foo/bar/baaz"), File("/foo/./bar/gav/../baaz").normalize())
assertEquals(File("/foo/bar/baaz"), File("/foo/bak/../bar/gav/../baaz").normalize())
assertEquals(File("../../bar"), File("../foo/../../bar").normalize())
// For Unix C:\windows is not correct so it's not the same as C:/windows
if (isBackslashSeparator) {
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("/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"))
// For Unix C:\path is not correct so it's cannot be automatically converted
if (isBackslashSeparator) {
assertEquals(File("C:\\Users\\Me\\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("bar"), File("").resolve("bar"))
assertEquals(File("foo/bar"), File("foo").resolve("bar"))
// should it normalize such paths?
// assertEquals(File("bar"), File("foo").resolve("../bar"))
// assertEquals(File("../bar"), File("foo").resolve("../../bar"))
// assertEquals(File("foo/bar"), File("foo").resolve("./bar"))
}
@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"))
// For Unix C:\path is not correct so it's cannot be automatically converted
if (isBackslashSeparator) {
assertEquals(File("C:\\Users\\Me\\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("").resolveSibling("gav"))
}
@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 testCopyTo() {
val srcFile = createTempFile()
val dstFile = createTempFile()
try {
srcFile.writeText("Hello, World!")
assertFailsWith(FileAlreadyExistsException::class, "copy do not overwrite existing file") {
srcFile.copyTo(dstFile)
}
var dst = srcFile.copyTo(dstFile, overwrite = true)
assertTrue(dst === dstFile)
compareFiles(srcFile, dst, "copy with overwrite over existing file")
assertTrue(dstFile.delete())
dst = srcFile.copyTo(dstFile)
compareFiles(srcFile, dst, "copy to new file")
assertTrue(dstFile.delete())
dstFile.mkdir()
val child = File(dstFile, "child")
child.createNewFile()
assertFailsWith(FileAlreadyExistsException::class, "copy with overwrite do not overwrite non-empty dir") {
srcFile.copyTo(dstFile, overwrite = true)
}
child.delete()
srcFile.copyTo(dstFile, overwrite = true)
assertEquals(srcFile.readText(), dstFile.readText(), "copy with overwrite over empty dir")
assertTrue(srcFile.delete())
assertTrue(dstFile.delete())
assertFailsWith(NoSuchFileException::class) {
srcFile.copyTo(dstFile)
}
srcFile.mkdir()
srcFile.resolve("somefile").writeText("some content")
dstFile.writeText("")
assertFailsWith(FileAlreadyExistsException::class, "copy dir do not overwrite file") {
srcFile.copyTo(dstFile)
}
srcFile.copyTo(dstFile, overwrite = true)
assertTrue(dstFile.isDirectory)
assertTrue(dstFile.listFiles()!!.isEmpty(), "only directory is copied, but not its content")
assertFailsWith(FileAlreadyExistsException::class, "copy dir do not overwrite dir") {
srcFile.copyTo(dstFile)
}
srcFile.copyTo(dstFile, overwrite = true)
assertTrue(dstFile.isDirectory)
assertTrue(dstFile.listFiles()!!.isEmpty(), "only directory is copied, but not its content")
dstFile.resolve("somefile2").writeText("some content2")
assertFailsWith(FileAlreadyExistsException::class, "copy dir do not overwrite dir") {
srcFile.copyTo(dstFile, overwrite = true)
}
}
finally {
srcFile.deleteRecursively()
dstFile.deleteRecursively()
}
}
@Test fun copyToNameWithoutParent() {
val currentDir = File("").absoluteFile!!
val srcFile = createTempFile()
val dstFile = createTempFile(directory = currentDir)
try {
srcFile.writeText("Hello, World!", Charsets.UTF_8)
dstFile.delete()
val dstRelative = File(dstFile.name)
srcFile.copyTo(dstRelative)
assertEquals(srcFile.readText(), dstFile.readText())
}
finally {
dstFile.delete()
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()
assertTrue(dir.deleteRecursively())
assertFalse(dir.exists())
assertTrue(dir.deleteRecursively())
}
@Test fun deleteRecursivelyWithFail() {
val basedir = FileTreeWalkTest.createTestFiles()
val restricted = File(basedir, "1")
try {
if (restricted.setReadable(false)) {
if (File(basedir, "7.txt").setReadable(false)) {
assertFalse(basedir.deleteRecursively(), "Expected incomplete recursive deletion.")
restricted.setReadable(true)
File(basedir, "7.txt").setReadable(true)
var i = 0
for (file in basedir.walkTopDown()) {
i++
}
assertEquals(6, i)
}
}
} finally {
restricted.setReadable(true)
File(basedir, "7.txt").setReadable(true)
basedir.deleteRecursively()
}
}
fun compareFiles(src: File, dst: File, message: String? = null) {
assertTrue(dst.exists())
assertEquals(src.isFile, dst.isFile, message)
if (dst.isFile) {
assertTrue(Arrays.equals(src.readBytes(), dst.readBytes()), message)
}
}
fun compareDirectories(src: File, dst: File) {
for (srcFile in src.walkTopDown()) {
val dstFile = dst.resolve(srcFile.relativeTo(src))
compareFiles(srcFile, dstFile)
}
}
@Test fun copyRecursively() {
val src = createTempDir()
val dst = createTempDir()
dst.delete()
fun check() = compareDirectories(src, dst)
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.writeText("hello")
file2.writeText("wazzup")
createTempDir(prefix = "d1_", directory = subDir2)
assertTrue(src.copyRecursively(dst))
check()
assertFailsWith(FileAlreadyExistsException::class) {
src.copyRecursively(dst)
}
var conflicts = 0
src.copyRecursively(dst) {
_: File, e: IOException ->
if (e is FileAlreadyExistsException) {
conflicts++
OnErrorAction.SKIP
} else {
throw e
}
}
assertEquals(2, conflicts)
if (subDir1.setReadable(false)) {
try {
dst.deleteRecursively()
var caught = false
assertTrue(src.copyRecursively(dst) {
_: File, e: IOException ->
if (e is AccessDeniedException) {
caught = true
OnErrorAction.SKIP
} else {
throw e
}
})
assertTrue(caught)
check()
} finally {
subDir1.setReadable(true)
}
}
src.deleteRecursively()
dst.deleteRecursively()
assertFailsWith(NoSuchFileException::class) {
src.copyRecursively(dst)
}
assertFalse(src.copyRecursively(dst) { _, _ -> OnErrorAction.TERMINATE })
} finally {
src.deleteRecursively()
dst.deleteRecursively()
}
}
@Test fun copyRecursivelyWithOverwrite() {
val src = createTempDir()
val dst = createTempDir()
fun check() = compareDirectories(src, dst)
try {
val srcFile = src.resolve("test")
val dstFile = dst.resolve("test")
srcFile.writeText("text1")
src.copyRecursively(dst)
srcFile.writeText("text1 modified")
src.copyRecursively(dst, overwrite = true)
check()
dstFile.delete()
dstFile.mkdir()
dstFile.resolve("subFile").writeText("subfile")
src.copyRecursively(dst, overwrite = true)
check()
srcFile.delete()
srcFile.mkdir()
srcFile.resolve("subFile").writeText("text2")
src.copyRecursively(dst, overwrite = true)
check()
}
finally {
src.deleteRecursively()
dst.deleteRecursively()
}
}
@Test fun helpers1() {
val str = "123456789\n"
System.setIn(str.byteInputStream())
val reader = System.`in`.bufferedReader()
assertEquals("123456789", reader.readLine())
val stringReader = str.reader()
assertEquals('1', stringReader.read().toChar())
assertEquals('2', stringReader.read().toChar())
assertEquals('3', stringReader.read().toChar())
}
@Test fun helpers2() {
val file = createTempFile()
val writer = file.printWriter()
val str1 = "Hello, world!"
val str2 = "Everything is wonderful!"
writer.println(str1)
writer.println(str2)
writer.close()
val reader = file.bufferedReader()
assertEquals(str1, reader.readLine())
assertEquals(str2, reader.readLine())
}
}
+42
View File
@@ -0,0 +1,42 @@
@file:kotlin.jvm.JvmVersion
package test.io
import kotlin.test.*
import java.io.Writer
import java.io.BufferedReader
class IOStreamsTest {
@Test fun testGetStreamOfFile() {
val tmpFile = createTempFile()
var writer: Writer? = null
try {
writer = tmpFile.outputStream().writer()
writer.write("Hello, World!")
} finally {
writer?.close()
}
val act: String?
var reader: BufferedReader? = null
try {
reader = tmpFile.inputStream().reader().buffered()
act = reader.readLine()
} finally {
reader?.close()
}
assertEquals("Hello, World!", act)
}
@Test fun testInputStreamIterator() {
val x = ByteArray(10) { it.toByte() }
val result = mutableListOf<Byte>()
x.inputStream().buffered().use { stream ->
for(b in stream) {
result += b
}
}
assertEquals(x.asList(), result)
}
}
+199
View File
@@ -0,0 +1,199 @@
@file:kotlin.jvm.JvmVersion
package test.io
import kotlin.test.*
import java.io.File
import java.io.Reader
import java.io.StringReader
import java.net.URL
import java.util.ArrayList
fun sample(): Reader = StringReader("Hello\nWorld");
class ReadWriteTest {
@Test fun testAppendText() {
val file = File.createTempFile("temp", System.nanoTime().toString())
file.writeText("Hello\n")
file.appendText("World\n")
file.appendText("Again")
assertEquals("Hello\nWorld\nAgain", file.readText())
assertEquals(listOf("Hello", "World", "Again"), file.readLines(Charsets.UTF_8))
file.deleteOnExit()
}
@Test fun reader() {
val list = ArrayList<String>()
/* TODO would be nicer maybe to write this as
reader.lines.forEach { ... }
as we could one day maybe write that as
for (line in reader.lines)
if the for(elem in thing) {...} statement could act as syntax sugar for
thing.forEach{ elem -> ... }
if thing is not an Iterable/array/Iterator but has a suitable forEach method
*/
sample().forEachLine {
list.add(it)
}
assertEquals(listOf("Hello", "World"), list)
assertEquals(listOf("Hello", "World"), sample().readLines())
sample().useLines {
assertEquals(listOf("Hello", "World"), it.toList())
}
var reader = StringReader("")
var c = 0
reader.forEachLine { c++ }
assertEquals(0, c)
reader = StringReader(" ")
reader.forEachLine { c++ }
assertEquals(1, c)
reader = StringReader(" \n")
c = 0
reader.forEachLine { c++ }
assertEquals(1, c)
reader = StringReader(" \n ")
c = 0
reader.forEachLine { c++ }
assertEquals(2, c)
}
@Test fun file() {
val file = File.createTempFile("temp", System.nanoTime().toString())
val writer = file.outputStream().writer().buffered()
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(Charsets.UTF_8, {
list.add(it)
})
assertEquals(arrayListOf("Hello", "World"), list)
assertEquals(arrayListOf("Hello", "World"), file.readLines())
file.useLines {
assertEquals(arrayListOf("Hello", "World"), it.toList())
}
val text = file.inputStream().reader().readText()
assertTrue(text.contains("Hello"))
assertTrue(text.contains("World"))
file.writeText("")
var c = 0
file.forEachLine { c++ }
assertEquals(0, c)
file.writeText(" ")
file.forEachLine { c++ }
assertEquals(1, c)
file.writeText(" \n")
c = 0
file.forEachLine { c++ }
assertEquals(1, c)
file.writeText(" \n ")
c = 0
file.forEachLine { c++ }
assertEquals(2, c)
file.deleteOnExit()
}
@Test fun testUse() {
val list = ArrayList<String>()
val reader = sample().buffered()
reader.use {
while (true) {
val line = it.readLine()
if (line != null)
list.add(line)
else
break
}
}
assertEquals(arrayListOf("Hello", "World"), list)
}
@Test fun testPlatformNullUse() {
fun <T> platformNull() = @Suppress("UNCHECKED_CAST") java.util.Collections.singleton(null as T).first()
val resource = platformNull<java.io.Closeable>()
val result = resource.use {
"ok"
}
assertEquals("ok", result)
}
@Test fun testURL() {
val url = URL("http://kotlinlang.org")
val text = url.readText()
assertFalse(text.isEmpty())
val text2 = url.readText(charset("UTF8"))
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.toList() }
val list2 = sample().useLines<ArrayList<String>>{ it.toCollection(arrayListOf()) }
assertEquals(listOf("Hello", "World"), list1)
assertEquals(listOf("Hello", "World"), list2)
}
@Test fun manualClose() {
val reader = sample().buffered()
try {
val list = reader.lineSequence().toList()
assertEquals(arrayListOf("Hello", "World"), list)
} finally {
reader.close()
}
}
@Test fun boundaryConditions() {
var reader = StringReader("").buffered()
assertEquals(emptyList(), reader.lineSequence().toList())
reader.close()
reader = StringReader(" ").buffered()
assertEquals(listOf(" "), reader.lineSequence().toList())
reader.close()
reader = StringReader(" \n").buffered()
assertEquals(listOf(" "), reader.lineSequence().toList())
reader.close()
reader = StringReader(" \n ").buffered()
assertEquals(listOf(" ", " "), reader.lineSequence().toList())
reader.close()
}
}
@@ -0,0 +1,87 @@
@file:kotlin.jvm.JvmVersion
package test.io
import java.io.*
import kotlin.test.*
private class Serial(val name: String) : Serializable {
override fun toString() = name
}
private data class DataType(val name: String, val value: Int, val percent: Double) : Serializable
private enum class EnumSingleton { INSTANCE }
private object ObjectSingleton : Serializable {
private fun readResolve(): Any = ObjectSingleton
}
private class OldSchoolSingleton private constructor() : Serializable {
private fun readResolve(): Any = INSTANCE
companion object {
val INSTANCE = OldSchoolSingleton()
}
}
class SerializableTest {
@Test fun testClosure() {
val tuple = Triple("Ivan", 12, Serial("serial"))
val fn = { tuple.toString() }
val deserialized = serializeAndDeserialize(fn)
assertEquals(fn(), deserialized())
}
@Test fun testComplexClosure() {
val y = 12
val fn1 = { x: Int -> (x + y).toString() }
val fn2: Int.(Int) -> String = { fn1(this + it) }
val deserialized = serializeAndDeserialize(fn2)
assertEquals(5.fn2(10), 5.deserialized(10))
}
@Test fun testDataClass() {
val data = DataType("name", 176, 1.4)
val deserialized = serializeAndDeserialize(data)
assertEquals(data, deserialized)
}
@Test fun testSingletons() {
assertTrue(EnumSingleton.INSTANCE === serializeAndDeserialize(EnumSingleton.INSTANCE))
assertTrue(OldSchoolSingleton.INSTANCE === serializeAndDeserialize(OldSchoolSingleton.INSTANCE))
assertTrue(ObjectSingleton === serializeAndDeserialize(ObjectSingleton))
}
}
public fun <T> serializeToByteArray(value: T): ByteArray {
val outputStream = ByteArrayOutputStream()
val objectOutputStream = ObjectOutputStream(outputStream)
objectOutputStream.writeObject(value)
objectOutputStream.close()
outputStream.close()
return outputStream.toByteArray()
}
public fun <T> deserializeFromByteArray(bytes: ByteArray): T {
val inputStream = ByteArrayInputStream(bytes)
val inputObjectStream = ObjectInputStream(inputStream)
@Suppress("UNCHECKED_CAST")
return inputObjectStream.readObject() as T
}
public fun <T> serializeAndDeserialize(value: T): T {
val bytes = serializeToByteArray(value)
return deserializeFromByteArray(bytes)
}
private fun hexToBytes(value: String): ByteArray = value.split(" ").map { Integer.parseInt(it, 16).toByte() }.toByteArray()
public fun <T> deserializeFromHex(value: String) = deserializeFromByteArray<T>(hexToBytes(value))
public fun <T> serializeToHex(value: T) =
serializeToByteArray(value).joinToString(" ") { (it.toInt() and 0xFF).toString(16).padStart(2, '0') }