Skip to content

Commit

Permalink
Fixed tree when entries have similar name + added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JetpackDuba committed Mar 28, 2024
1 parent 3d48a31 commit 8ef62d1
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 5 deletions.
42 changes: 37 additions & 5 deletions src/main/kotlin/com/jetpackduba/gitnuro/ui/tree_files/Tree.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.jetpackduba.gitnuro.ui.tree_files

import arrow.core.compareTo
import com.jetpackduba.gitnuro.system.systemSeparator
import kotlin.math.max

fun <T> entriesToTreeEntry(
entries: List<T>,
Expand All @@ -9,20 +11,26 @@ fun <T> entriesToTreeEntry(
): List<TreeItem<T>> {
return entries
.asSequence()
.sortedWith { entry1, entry2 ->
val path1 = onGetEntryPath(entry1)
val path2 = onGetEntryPath(entry2)

PathsComparator().compare(path1, path2)
}
.map { entry ->
val filePath = onGetEntryPath(entry)
val parts = filePath.split(systemSeparator)

parts.mapIndexed { index, partName ->
if (index == parts.lastIndex) {
val isParentContracted = treeContractedDirs.none { contractedDir ->
val isParentDirectoryContracted = treeContractedDirs.any { contractedDir ->
filePath.startsWith(contractedDir + systemSeparator)
}

if (isParentContracted) {
TreeItem.File(entry, partName, filePath, index)
} else {
if (isParentDirectoryContracted) {
null
} else {
TreeItem.File(entry, partName, filePath, index)
}
} else {
val dirPath = parts.slice(0..index).joinToString(systemSeparator)
Expand All @@ -45,10 +53,34 @@ fun <T> entriesToTreeEntry(
.flatten()
.filterNotNull()
.distinct()
.sortedBy { it.fullPath }
.toList()
}

private class PathsComparator : Comparator<String> {
override fun compare(path1: String, path2: String): Int {
val path1Parts = path1.split(systemSeparator)
val path2Parts = path2.split(systemSeparator)

path1Parts.compareTo(path2Parts)

val maxIndex = max(path1Parts.count(), path2Parts.count())

for (i in 0 until maxIndex) {
val part1 = path1Parts.getOrNull(i) ?: return -1
val part2 = path2Parts.getOrNull(i) ?: return 1

val comparison = part1.compareTo(part2)

if (comparison != 0) {
return comparison
}
}

return 0
}

}

sealed interface TreeItem<out T> {
val fullPath: String
val displayName: String
Expand Down
80 changes: 80 additions & 0 deletions src/test/kotlin/com/jetpackduba/gitnuro/ui/tree_files/TreeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.jetpackduba.gitnuro.ui.tree_files

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test

class TreeTest {

@Test
fun `test entriesToTreeEntry with empty entries`() {
val entries = emptyList<String>()
val treeContractedDirs = emptyList<String>()
val result = entriesToTreeEntry(entries, treeContractedDirs) { it }
assertTrue(result.isEmpty())
}

@Test
fun `test entriesToTreeEntry with single file entry`() {
val entries = listOf("file.txt")
val treeContractedDirs = emptyList<String>()
val result = entriesToTreeEntry(entries, treeContractedDirs) { it }

assertEquals(listOf(TreeItem.File("file.txt", "file.txt", "file.txt", 0)), result)
}

@Test
fun `test entriesToTreeEntry with multiple file entries`() {
val entries = listOf("dir1/file1.txt", "dir2/file2.txt", "dir3/file3.txt")
val treeContractedDirs = emptyList<String>()
val result = entriesToTreeEntry(entries, treeContractedDirs) { it }
val expected = listOf(
TreeItem.Dir(true, "dir1", "dir1", 0),
TreeItem.File("dir1/file1.txt", "file1.txt", "dir1/file1.txt", 1),
TreeItem.Dir(true, "dir2", "dir2", 0),
TreeItem.File("dir2/file2.txt", "file2.txt", "dir2/file2.txt", 1),
TreeItem.Dir(true, "dir3", "dir3", 0),
TreeItem.File("dir3/file3.txt", "file3.txt", "dir3/file3.txt", 1)
)
assertEquals(expected, result)
}

@Test
fun `test entriesToTreeEntry with similar names`() {
val entries = listOf(
"webpack/webpack.config2.ts",
"webpack/webpack.config.ts",
"webpack-plugin.ts",
"dir1/file3.txt"
)
val treeContractedDirs = emptyList<String>()
val result = entriesToTreeEntry(entries, treeContractedDirs) { it }
val expected = listOf(
TreeItem.Dir(true, "dir1", "dir1", 0),
TreeItem.File("dir1/file3.txt", "file3.txt", "dir1/file3.txt", 1),
TreeItem.Dir(true, "webpack", "webpack", 0),
TreeItem.File("webpack/webpack.config.ts", "webpack.config.ts", "webpack/webpack.config.ts", 1),
TreeItem.File("webpack/webpack.config2.ts", "webpack.config2.ts", "webpack/webpack.config2.ts", 1),
TreeItem.File("webpack-plugin.ts", "webpack-plugin.ts", "webpack-plugin.ts", 0)
)
assertEquals(expected, result)
}

@Test
fun `test entriesToTreeEntry with contracted directories`() {
val entries = listOf(
"webpack/webpack.config2.ts",
"webpack/webpack.config.ts",
"webpack-plugin.ts",
"dir1/file3.txt"
)
val treeContractedDirs = listOf<String>("webpack", "dir1")
val result = entriesToTreeEntry(entries, treeContractedDirs) { it }
val expected = listOf(
TreeItem.Dir(false, "dir1", "dir1", 0),
TreeItem.Dir(false, "webpack", "webpack", 0),
TreeItem.File("webpack-plugin.ts", "webpack-plugin.ts", "webpack-plugin.ts", 0)
)
assertEquals(expected, result)
}
}

0 comments on commit 8ef62d1

Please sign in to comment.