diff --git a/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt b/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt index cfd9d06b6..371278889 100644 --- a/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt +++ b/base/src/test/kotlin/de/staropensource/engine/base/utility/FileAccessTest.kt @@ -20,13 +20,17 @@ package de.staropensource.engine.base.utility +import de.staropensource.engine.base.utility.FileAccess.Type import de.staropensource.engine.testing.TestBase import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.CsvSource +import org.junit.jupiter.params.provider.ValueSource import java.io.File +import kotlin.test.assertFalse import kotlin.test.assertNotNull +import kotlin.test.assertTrue @Suppress("EmptyFunctionBlock") class FileAccessTest : TestBase() { @@ -40,14 +44,16 @@ class FileAccessTest : TestBase() { "/some/test/file", "/some/test/file" "\very\nice\test\file.txt", "/very/nice/test/file.txt" "/./did/somebody\\/say\\yoga?", "/did/somebody/say/yoga?" - "test.txt", "+%test.txt"""" + "test.txt", "+/test.txt"""" ) fun toStringTest(supplyValue: String, compareValue: String) { assertEquals( compareValue - .replace("+", "${System.getProperty("user.dir")}") - .replace("%", File.separator), - FileAccess(supplyValue).toString() + .replace("+", FileAccess.temporaryCacheDirectory!!.toString()), + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .toString() ) } @@ -64,9 +70,12 @@ class FileAccessTest : TestBase() { fun toStringRaw(supplyValue: String, compareValue: String) { assertEquals( compareValue - .replace("+", "${System.getProperty("user.dir")}") + .replace("+", FileAccess.temporaryCacheDirectory!!.toString()) .replace("%", File.separator), - FileAccess(supplyValue).toStringRaw() + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .toStringRaw() ) } @@ -83,7 +92,10 @@ class FileAccessTest : TestBase() { fun getBaseName(supplyValue: String, compareValue: String) { assertEquals( compareValue, - FileAccess(supplyValue).getBaseName() + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .getBaseName() ) } @ParameterizedTest @@ -95,14 +107,17 @@ class FileAccessTest : TestBase() { "\very\nice\test\file.txt", "/very/nice/test" "/./did/somebody\\/say\\yoga?", "/did/somebody/say" "test.txt", "+" - "configs/default.conf", "+%configs"""" + "configs/default.conf", "+/configs"""" ) fun parent(supplyValue: String, compareValue: String) { assertEquals( compareValue - .replace("+", "${System.getProperty("user.dir")}") - .replace("%", File.separator), - FileAccess(supplyValue).parent().toString() + .replace("+", FileAccess.temporaryCacheDirectory!!.toString()), + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .parent() + .toString() ) } @@ -111,96 +126,401 @@ class FileAccessTest : TestBase() { // These tests are executed on FileAccess' default paths @Test fun getTemporaryCacheDirectory() { - assertNotNull(FileAccess.temporaryCacheDirectory) + assertEquals( + Type.DIRECTORY, + FileAccess + .temporaryCacheDirectory + ?.getType() + ) } @Test fun getPersistentCacheDirectory() { - assertNotNull(FileAccess.persistentCacheDirectory) + assertEquals( + Type.DIRECTORY, + FileAccess + .persistentCacheDirectory + ?.getType() + ) } @Test fun getHomeDirectory() { - assertNotNull(FileAccess.homeDirectory) + assertEquals( + Type.DIRECTORY, + FileAccess + .homeDirectory + ?.getType() + ) } @Test fun getConfigDirectory() { - assertNotNull(FileAccess.configDirectory) + assertEquals( + Type.DIRECTORY, + FileAccess + .configDirectory + ?.getType() + ) } @Test fun getDataDirectory() { - assertNotNull(FileAccess.dataDirectory) + assertEquals( + Type.DIRECTORY, + FileAccess + .dataDirectory + ?.getType() + ) } @Test - fun exists() { - + fun existsVoid() { + assertFalse( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsVoid.exist") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .exists() + ) } @Test - fun getType() { - + fun existsFile() { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsFile.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createFile() + .exists() + ) } @Test - fun isSymbolicLink() { + fun existsDirectory() { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsDirectory.d") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createDirectory() + .exists() + ) + } + @ParameterizedTest + @ValueSource(booleans = [ + true, + false + ]) + fun existsSymlinkReal(noFollowSymbolicLink: Boolean) { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsSymlinkReal.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess.temporaryCacheDirectory!! + .traverse("existsSymlinkReal.target.txt") + .createFile() + .verifyIsFile(), + false + ) + .exists(noFollowSymbolicLink = noFollowSymbolicLink) + ) + } + + @ParameterizedTest + @ValueSource(booleans = [ + true, + false + ]) + fun existsSymlinkFake(noFollowSymbolicLink: Boolean) { + assertEquals( + noFollowSymbolicLink, + FileAccess + .temporaryCacheDirectory!! + .traverse("existsSymlinkFake.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsSymlinkFake.target.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true), + false + ) + .exists(noFollowSymbolicLink = noFollowSymbolicLink) + ) + } + + @ParameterizedTest + @ValueSource(booleans = [ + true, + false + ]) + fun existsHardlinkReal(noFollowSymbolicLink: Boolean) { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsHardlinkReal.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess.temporaryCacheDirectory!! + .traverse("existsHardlinkReal.target.txt") + .createFile() + .verifyIsFile(), + true + ) + .exists(noFollowSymbolicLink = noFollowSymbolicLink) + ) + } + + @ParameterizedTest + @ValueSource(booleans = [ + true, + false + ]) + fun existsHardlinkFake(noFollowSymbolicLink: Boolean) { + val target: FileAccess = FileAccess + .temporaryCacheDirectory!! + .traverse("existsHardlinkFake.target.txt") + .createFile() + .verifyIsFile() + val link: FileAccess = FileAccess + .temporaryCacheDirectory!! + .traverse("existsHardlinkFake.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + target, + true + ) + + // Delete target + target.delete() + + assertTrue(link.exists(noFollowSymbolicLink = noFollowSymbolicLink)) } @Test - fun isHidden() { - + fun getTypeVoid() { + assertEquals( + Type.VOID, + FileAccess + .temporaryCacheDirectory!! + .traverse("getTypeVoid.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .getType() + ) } @Test - fun isReadable() { - + fun getTypeFile() { + assertEquals( + Type.FILE, + FileAccess + .temporaryCacheDirectory!! + .traverse("getTypeFile.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createFile() + .verifyIsFile() + .getType() + ) } @Test - fun isWritable() { - + fun getTypeDirectory() { + assertEquals( + Type.DIRECTORY, + FileAccess + .temporaryCacheDirectory!! + .traverse("getTypeDirectory.d") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createDirectory() + .verifyIsDirectory() + .getType() + ) } @Test - fun isExecutable() { - + fun isSymbolicLinkReal() { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("isSymbolicLinkReal.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess.temporaryCacheDirectory!! + .traverse("existsSymlinkReal.target.txt") + .createFile() + .verifyIsFile(), + false + ) + .isSymbolicLink() + ) } @Test - fun getPosixPermissions() { - + fun isSymbolicLinkFake() { + assertTrue( + FileAccess + .temporaryCacheDirectory!! + .traverse("isSymbolicLinkFake.test.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess + .temporaryCacheDirectory!! + .traverse("existsSymlinkFake.target.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true), + false + ) + .isSymbolicLink() + ) } - @Test - fun getLinkDestination() { + @ParameterizedTest + @CsvSource( + delimiter = ',', + quoteCharacter = '"', + textBlock = """ + "very\\\cool\\/directory/structure", "+%very/cool/directory/structure" + "some.spot", "+%some.spot"""" + ) + fun getLinkDestinationReal(supplyValue: String, compareValue: String) { + assertEquals( + compareValue + .replace("+", FileAccess.temporaryCacheDirectory!!.toString()) + .replace("%", File.separator), + FileAccess + .temporaryCacheDirectory!! + .traverse("getLinkDestinationSymlinkReal.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .createFile() + .verifyIsFile(), + false + ) + .getLinkDestination() + .toString() + ) + } + + @ParameterizedTest + @CsvSource( + delimiter = ',', + quoteCharacter = '"', + textBlock = """ + "getLinkDestinationSymlinkFake.d/very\\\cool\\/directory/structure", "+%getLinkDestinationSymlinkFake.d/very/cool/directory/structure" + "getLinkDestinationSymlinkFake.d/some.spot", "+%getLinkDestinationSymlinkFake.d/some.spot"""" + ) + fun getLinkDestinationFake(supplyValue: String, compareValue: String) { + assertEquals( + compareValue + .replace("+", FileAccess.temporaryCacheDirectory!!.toString()) + .replace("%", File.separator), + FileAccess + .temporaryCacheDirectory!! + .traverse("getLinkDestinationSymlinkFake.link.txt") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createLink( + FileAccess + .temporaryCacheDirectory!! + .traverse(supplyValue) + .delete() + .verifyNotExists(noFollowSymbolicLink = true), + false + ) + .getLinkDestination() + .toString() + ) } @Test fun getFileSystem() { - } - - @Test - fun isFilesystemPosixCompliant() { + assertNotNull( + FileAccess + .temporaryCacheDirectory!! + .traverse("justSomeTestFile") + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .getFileSystem() + ) } @Test fun getFilesystemRestrictedNames() { + val file: FileAccess = + FileAccess + .temporaryCacheDirectory!! + .traverse("test/file") + + assertTrue( + file + .getFilesystemRestrictedNames() + .toRegex() + .containsMatchIn(file.toString()) + ) } - @Test - fun createFile() { + @ParameterizedTest + @ValueSource(strings = [ + "createFile.d/cool.test.file", + "createFile.d/something/in/directories.txt", + "createFile.d/hello.world" + ]) + fun createFile(path: String) { + assertEquals( + Type.FILE, + FileAccess + .temporaryCacheDirectory!! + .traverse(path) + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createFile() + .getType() + ) } - @Test - fun createDirectory() { + @ParameterizedTest + @ValueSource(strings = [ + "createDirectory.d/some/directory/stuff", + "createDirectory.d/directories/are/very/cool", + "createDirectory.d/very\\old/operating/systems\\only\\had/the/top/level\\and/at/most\\user/folders/without\\any\\/security/measures" + ]) + fun createDirectory(path: String) { + assertEquals( + Type.DIRECTORY, + FileAccess + .temporaryCacheDirectory!! + .traverse(path) + .delete() + .verifyNotExists(noFollowSymbolicLink = true) + .createDirectory() + .getType() + ) } - @Test - fun createLink() { - } + // The createLink method is pretty much + // already covered by the exists* link tests @Test fun move() {