diff --git a/.gitignore b/.gitignore
index b63da45..29c74bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,4 +39,7 @@ bin/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+
+### Custom ###
+_tmp/
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index f9163b4..ce1c62c 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 58603c7..256e71b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -18,5 +18,5 @@ tasks.test {
}
kotlin {
- jvmToolchain(8)
+ jvmToolchain(11)
}
\ No newline at end of file
diff --git a/src/main/kotlin/filesystem/FSCreator.kt b/src/main/kotlin/filesystem/FSCreator.kt
index 1a98444..3c277f0 100644
--- a/src/main/kotlin/filesystem/FSCreator.kt
+++ b/src/main/kotlin/filesystem/FSCreator.kt
@@ -1,9 +1,13 @@
package filesystem
+import java.nio.file.FileAlreadyExistsException
+import java.nio.file.FileSystemException
import java.nio.file.Files
import java.nio.file.Path
class FSCreator {
+ // Create entry, leaving existing folders' contents, but overwriting existing files.
+ @Throws(FileSystemException::class)
fun create(entryToCreate: FSEntry, destination: String) {
val queue = ArrayDeque>()
queue.add(entryToCreate to Path.of(destination))
@@ -17,8 +21,9 @@ class FSCreator {
is FSFolder -> Files.createDirectory(path)
}
} catch (_: FileAlreadyExistsException) {} // Allow files/folders to already exist.
- if (entry is FSFolder) {
- queue.addAll(entry.entries.map { it to path })
+ when (entry) {
+ is FSFile -> Files.write(path, entry.content.toByteArray())
+ is FSFolder -> queue.addAll(entry.entries.map { it to path })
}
}
}
diff --git a/src/test/kotlin/filesystem/FSCreatorTest.kt b/src/test/kotlin/filesystem/FSCreatorTest.kt
new file mode 100644
index 0000000..249c0bf
--- /dev/null
+++ b/src/test/kotlin/filesystem/FSCreatorTest.kt
@@ -0,0 +1,103 @@
+package filesystem
+
+import org.junit.jupiter.api.*
+import java.nio.file.FileSystemException
+import java.nio.file.Files
+import java.nio.file.Path
+import java.util.concurrent.TimeUnit
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class FSCreatorTest {
+ private val creator = FSCreator()
+
+ @BeforeEach
+ fun `before each`() {
+ assertDoesNotThrow("should create _tmp directory") {
+ Files.createDirectory(Path.of("_tmp"))
+ }
+ }
+
+ @AfterEach
+ fun `after each`() {
+ assertDoesNotThrow("should delete _tmp directory") {
+ deleteRecursive(Path.of("_tmp"))
+ }
+ }
+
+ @Test
+ fun `create entries`() {
+ val readme = FSFile("README", "Hello World!")
+ val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5")
+ val maingo = FSFile("main.go", "package main\n\nimport \"example.com/hello-world/utils\"\n\n" +
+ "func main() {\n\tprintln(\"Hello World!\")\n}")
+ val helloworldgo = FSFile("hello-world.go", "package utils\n\nfunc PrintHelloWorld() {\n" +
+ "\tprintln(\"Hello World!\")\n}")
+ assertDoesNotThrow("should create entries") {
+ creator.create(FSFolder("folder", listOf(
+ readme,
+ gomod,
+ maingo,
+ FSFolder("utils", listOf(
+ helloworldgo
+ ))
+ )), "_tmp")
+ }
+ // If objects don't exist, these functions will throw anyway, so don't explicitly check for existence.
+ // Similarly, don't explicitly check if an object is a directory.
+ assertEquals(readme.content, Files.readString(Path.of("_tmp/folder", readme.name)))
+ assertEquals(gomod.content, Files.readString(Path.of("_tmp/folder", gomod.name)))
+ assertEquals(maingo.content, Files.readString(Path.of("_tmp/folder", maingo.name)))
+ assertEquals(helloworldgo.content, Files.readString(Path.of("_tmp/folder/utils", helloworldgo.name)))
+ }
+
+ @Test
+ fun `create existing entries`() {
+ assertDoesNotThrow("creation one") {
+ creator.create(FSFolder("folder", listOf(
+ FSFolder("sub-folder", listOf(
+ FSFile("hi", "hi")
+ )),
+ FSFolder("another-folder", listOf()),
+ FSFile("1.txt", "One!"),
+ FSFile("2.txt", "Two!")
+ )), "_tmp")
+ }
+ assertDoesNotThrow("creation two") {
+ creator.create(FSFolder("folder", listOf(
+ FSFolder("another-folder", listOf(
+ FSFolder("secrets", listOf(
+ FSFile("secret", "P4ssW0rd")
+ ))
+ )),
+ FSFile("1.txt", "One is a good number"),
+ FSFile("3.txt", "Three!")
+ )), "_tmp")
+ }
+ assertEquals("hi", Files.readString(Path.of("_tmp/folder/sub-folder/hi")))
+ assertEquals("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret")))
+ assertEquals("One is a good number", Files.readString(Path.of("_tmp/folder/1.txt")))
+ assertEquals("Two!", Files.readString(Path.of("_tmp/folder/2.txt")))
+ assertEquals("Three!", Files.readString(Path.of("_tmp/folder/3.txt")))
+ }
+
+ @Test
+ @Timeout(500, unit = TimeUnit.MILLISECONDS) // in case implementation starts trying to handle recursion
+ fun `create throws on recursive folder`() {
+ val files = mutableListOf()
+ val folder = FSFolder("folder", files)
+ files.add(folder)
+ assertThrows {
+ creator.create(folder, "_tmp")
+ }
+ }
+}
+
+fun deleteRecursive(path: Path) {
+ if (Files.isDirectory(path)) {
+ for (child in Files.list(path)) {
+ deleteRecursive(child)
+ }
+ }
+ Files.delete(path)
+}
\ No newline at end of file