diff --git a/src/main/kotlin/com/mituuz/fuzzier/actions/FuzzyAction.kt b/src/main/kotlin/com/mituuz/fuzzier/actions/FuzzyAction.kt index 0de63db7..cb3e2c1e 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/actions/FuzzyAction.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/actions/FuzzyAction.kt @@ -73,8 +73,6 @@ abstract class FuzzyAction : AnAction() { protected val globalState = service().state protected var defaultDoc: Document? = null private val fileTypeManager = FileTypeManager.getInstance() - - val fuzzierUtil = FuzzierUtil() protected open var currentUpdateListContentJob: Job? = null protected open var actionScope: CoroutineScope? = null @@ -104,7 +102,7 @@ abstract class FuzzyAction : AnAction() { val project = actionEvent.project if (project != null) { projectState = project.service().state - fuzzierUtil.parseModules(project) + FuzzierUtil.parseModules(project) setCustomHandlers() actionScope?.cancel() actionScope = CoroutineScope(SupervisorJob() + Dispatchers.Default) diff --git a/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt b/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt index 6417e43f..09f63a26 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/components/TestBenchComponent.kt @@ -69,8 +69,7 @@ class TestBenchComponent : JPanel(), Disposable { val project = ProjectManager.getInstance().openProjects[0] projectState = project.service().state - val fuzzierUtil = FuzzierUtil() - fuzzierUtil.parseModules(project) + FuzzierUtil.parseModules(project) liveSettingsComponent = settingsComponent layout = GridLayoutManager(2, 1) diff --git a/src/main/kotlin/com/mituuz/fuzzier/grep/backend/FuzzierGrep.kt b/src/main/kotlin/com/mituuz/fuzzier/grep/backend/FuzzierGrep.kt index 332d3fe6..ea4154ab 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/grep/backend/FuzzierGrep.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/grep/backend/FuzzierGrep.kt @@ -35,7 +35,6 @@ import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.PsiSearchHelper -import com.intellij.openapi.components.service import com.intellij.util.Processor import com.mituuz.fuzzier.entities.CaseMode import com.mituuz.fuzzier.entities.FuzzyContainer @@ -50,7 +49,6 @@ import javax.swing.DefaultListModel object FuzzierGrep : BackendStrategy { override val name = "fuzzier" - private val fuzzierUtil = FuzzierUtil() private val searchMatcher = SearchMatcher() override suspend fun handleSearch( @@ -67,6 +65,7 @@ object FuzzierGrep : BackendStrategy { val maxResults = service().state.fileListLimit val batcher = ResultBatcher() + val modules = project.service().state.modules for (file in files) { currentCoroutineContext().ensureActive() @@ -83,7 +82,8 @@ object FuzzierGrep : BackendStrategy { val found = searchMatcher.matchesLine(line, searchString, grepConfig.caseMode) if (found) { - val (filePath, basePath) = fuzzierUtil.extractModulePath(file.path, project) + val (filePath, basePath) = + FuzzierUtil.extractModulePath(file.path, modules) fileMatches.add( RowContainer( filePath, diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/Fuzzier.kt b/src/main/kotlin/com/mituuz/fuzzier/search/Fuzzier.kt index d79d2e90..ad402980 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/search/Fuzzier.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/search/Fuzzier.kt @@ -28,21 +28,21 @@ import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.fileEditor.FileEditorManager -import com.intellij.openapi.fileEditor.impl.EditorHistoryManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.util.SingleAlarm import com.mituuz.fuzzier.actions.filesystem.FilesystemAction import com.mituuz.fuzzier.components.FuzzyFinderComponent -import com.mituuz.fuzzier.entities.FuzzyContainer import com.mituuz.fuzzier.intellij.files.FileOpeningUtil import com.mituuz.fuzzier.intellij.iteration.IntelliJIterationFileCollector import com.mituuz.fuzzier.intellij.iteration.IterationFileCollector +import com.mituuz.fuzzier.search.initialview.DefaultInitialListModelProvider +import com.mituuz.fuzzier.search.initialview.InitialListModelProvider +import com.mituuz.fuzzier.search.initialview.addFileToRecentlySearchedFiles import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService import com.mituuz.fuzzier.ui.bindings.ActivationBindings import com.mituuz.fuzzier.ui.popup.PopupConfig -import com.mituuz.fuzzier.util.InitialViewHandler import javax.swing.DefaultListModel open class Fuzzier : FilesystemAction() { @@ -54,6 +54,14 @@ open class Fuzzier : FilesystemAction() { return IntelliJIterationFileCollector(projectState) } + protected open fun getInitialViewProvider(project: Project): InitialListModelProvider { + return DefaultInitialListModelProvider( + project, + globalState, + projectState, + ) + } + override fun buildFileFilter(project: Project): (VirtualFile) -> Boolean = { vf -> !vf.isDirectory } @@ -133,7 +141,11 @@ open class Fuzzier : FilesystemAction() { globalState.newTab ) { if (selectedValue != null) { - InitialViewHandler.addFileToRecentlySearchedFiles(selectedValue, projectState, globalState) + addFileToRecentlySearchedFiles( + selectedValue, + projectState, + globalState + ) } popup.cancel() } @@ -144,27 +156,9 @@ open class Fuzzier : FilesystemAction() { component.fileList.setPaintBusy(true) ApplicationManager.getApplication().executeOnPooledThread { try { - val editorHistoryManager = EditorHistoryManager.getInstance(project) - - val listModel = when (globalState.recentFilesMode) { - FuzzierGlobalSettingsService.RecentFilesMode.RECENT_PROJECT_FILES -> InitialViewHandler.getRecentProjectFiles( - globalState, - fuzzierUtil, - editorHistoryManager, - project - ) - - FuzzierGlobalSettingsService.RecentFilesMode.RECENTLY_SEARCHED_FILES -> InitialViewHandler.Companion.getRecentlySearchedFiles( - projectState - ) - - else -> { - DefaultListModel() - } - } - + val initialListModel = getInitialViewProvider(project).invoke() ApplicationManager.getApplication().invokeLater { - component.refreshModel(listModel, getCellRenderer()) + component.refreshModel(initialListModel, getCellRenderer()) } } finally { component.fileList.setPaintBusy(false) diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/FuzzierOpenTabs.kt b/src/main/kotlin/com/mituuz/fuzzier/search/FuzzierOpenTabs.kt index 5cc17de3..e4e1b493 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/search/FuzzierOpenTabs.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/search/FuzzierOpenTabs.kt @@ -24,12 +24,22 @@ package com.mituuz.fuzzier.search +import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.openapi.project.Project import com.mituuz.fuzzier.intellij.iteration.IterationFileCollector import com.mituuz.fuzzier.intellij.iteration.OpenTabsCollector +import com.mituuz.fuzzier.search.initialview.InitialListModelProvider +import com.mituuz.fuzzier.search.initialview.OpenTabsInitialListModelProvider class FuzzierOpenTabs : Fuzzier() { override var popupTitle: String = "Fuzzy Search (Open Tabs)" + override fun getInitialViewProvider(project: Project): InitialListModelProvider { + val modules = projectState.modules + val openFiles = FileEditorManager.getInstance(project).openFiles + return OpenTabsInitialListModelProvider(modules, openFiles) + } + override fun createCollector(): IterationFileCollector { return OpenTabsCollector() } diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/initialview/DefaultInitialListModelProvider.kt b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/DefaultInitialListModelProvider.kt new file mode 100644 index 00000000..57ded887 --- /dev/null +++ b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/DefaultInitialListModelProvider.kt @@ -0,0 +1,97 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.intellij.openapi.fileEditor.impl.EditorHistoryManager +import com.intellij.openapi.project.Project +import com.mituuz.fuzzier.entities.FuzzyContainer +import com.mituuz.fuzzier.entities.OrderedContainer +import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService +import com.mituuz.fuzzier.settings.FuzzierSettingsService +import com.mituuz.fuzzier.util.FuzzierUtil +import javax.swing.DefaultListModel + +class DefaultInitialListModelProvider( + val project: Project, + val globalState: FuzzierGlobalSettingsService.State, + val projectState: FuzzierSettingsService.State, +) : InitialListModelProvider { + override fun invoke(): DefaultListModel { + return when (globalState.recentFilesMode) { + FuzzierGlobalSettingsService.RecentFilesMode.RECENT_PROJECT_FILES -> { + getRecentProjectFiles(project) + } + + FuzzierGlobalSettingsService.RecentFilesMode.RECENTLY_SEARCHED_FILES -> { + getRecentlySearchedFiles() + } + + else -> { + DefaultListModel() + } + } + } + + fun getRecentProjectFiles( + project: Project, + ): DefaultListModel { + val editorHistoryManager = EditorHistoryManager.getInstance(project) + val editorHistory = editorHistoryManager.fileList + val listModel = DefaultListModel() + val limit = globalState.fileListLimit + + // Start from the end of editor history (most recent file) + var i = editorHistory.size - 1 + while (i >= 0 && listModel.size() < limit) { + val file = editorHistory[i] + val filePathAndModule = FuzzierUtil.extractModulePath(file.path, projectState.modules) + // Don't add files that do not have a module path in the project + if (filePathAndModule.second == "") { + i-- + continue + } + val orderedContainer = OrderedContainer( + filePathAndModule.first, filePathAndModule.second, file.name + ) + listModel.addElement(orderedContainer) + i-- + } + + return listModel + } + + fun getRecentlySearchedFiles(): DefaultListModel { + val result = DefaultListModel() + projectState.getRecentlySearchedFilesAsFuzzyMatchContainer() + .elements() + .toList() + .filterNotNull() + .reversed() + .let { + result.addAll(it) + } + return result + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/initialview/InitialListModelProvider.kt b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/InitialListModelProvider.kt new file mode 100644 index 00000000..683c4763 --- /dev/null +++ b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/InitialListModelProvider.kt @@ -0,0 +1,30 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.mituuz.fuzzier.entities.FuzzyContainer +import javax.swing.DefaultListModel + +typealias InitialListModelProvider = () -> DefaultListModel \ No newline at end of file diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProvider.kt b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProvider.kt new file mode 100644 index 00000000..22aaec4b --- /dev/null +++ b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProvider.kt @@ -0,0 +1,56 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.intellij.openapi.vfs.VirtualFile +import com.mituuz.fuzzier.entities.FuzzyContainer +import com.mituuz.fuzzier.entities.OrderedContainer +import com.mituuz.fuzzier.util.FuzzierUtil +import javax.swing.DefaultListModel + +class OpenTabsInitialListModelProvider( + private val modules: Map, + private val openFiles: Array +) : InitialListModelProvider { + override fun invoke(): DefaultListModel { + val listModel = DefaultListModel() + + for (vf in openFiles) { + if (!vf.isDirectory) { + val filePathAndModule = FuzzierUtil.extractModulePath(vf.path, modules) + // Don't add files that do not have a module path in the project + if (filePathAndModule.second == "") { + continue + } + val orderedContainer = OrderedContainer( + filePathAndModule.first, filePathAndModule.second, vf.name + ) + listModel.add(0, orderedContainer) + } + } + + return listModel + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtil.kt b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtil.kt new file mode 100644 index 00000000..25001289 --- /dev/null +++ b/src/main/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtil.kt @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.mituuz.fuzzier.entities.FuzzyContainer +import com.mituuz.fuzzier.entities.FuzzyMatchContainer +import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService +import com.mituuz.fuzzier.settings.FuzzierSettingsService +import javax.swing.DefaultListModel + +fun addFileToRecentlySearchedFiles( + fuzzyContainer: FuzzyContainer, + projectState: FuzzierSettingsService.State, + globalState: FuzzierGlobalSettingsService.State +) { + val listModel: DefaultListModel = + projectState.getRecentlySearchedFilesAsFuzzyMatchContainer() + + var i = 0 + while (i < listModel.size) { + if (listModel[i].filePath == fuzzyContainer.filePath) { + listModel.remove(i) + } else { + i++ + } + } + + while (listModel.size > globalState.fileListLimit - 1) { + listModel.remove(listModel.size - 1) + } + + if (fuzzyContainer is FuzzyMatchContainer) { + listModel.addElement(fuzzyContainer) + projectState.recentlySearchedFiles = + FuzzyMatchContainer.SerializedMatchContainer.fromListModel(listModel) + } +} diff --git a/src/main/kotlin/com/mituuz/fuzzier/util/FuzzierUtil.kt b/src/main/kotlin/com/mituuz/fuzzier/util/FuzzierUtil.kt index 1687d875..7084f495 100644 --- a/src/main/kotlin/com/mituuz/fuzzier/util/FuzzierUtil.kt +++ b/src/main/kotlin/com/mituuz/fuzzier/util/FuzzierUtil.kt @@ -49,84 +49,83 @@ class FuzzierUtil { return ret } - } - /** - * For each module in the project, check if the file path contains the module path. - * @return a pair of the file path (with the module path removed) and the module path - */ - fun extractModulePath(filePath: String, project: Project): Pair { - val modules = project.service().state.modules - for (modulePath in modules.values) { - if (filePath.contains(modulePath)) { - val file = filePath.removePrefix(modulePath) - return Pair(file, modulePath) + /** + * For each module in the project, check if the file path contains the module path. + * @return a pair of the file path (with the module path removed) and the module path + */ + fun extractModulePath(filePath: String, modules: Map): Pair { + for (modulePath in modules.values) { + if (filePath.contains(modulePath)) { + val file = filePath.removePrefix(modulePath) + return Pair(file, modulePath) + } } + return Pair(filePath, "") } - return Pair(filePath, "") - } - /** - * Parse all modules in the project and find the shortest base path for each of them. - * Combines similar module paths to the shortest possible form. - * - * Populates `FuzzierSettings.state.modules`-field - */ - fun parseModules(project: Project) { - val moduleManager = ModuleManager.getInstance(project) - - // Gather all modules and paths into a list - val moduleList: MutableList = ArrayList() - for (module in moduleManager.modules) { - val modulePath = getModulePath(module) ?: continue - moduleList.add(ModuleContainer(module.name, modulePath)) - } + /** + * Parse all modules in the project and find the shortest base path for each of them. + * Combines similar module paths to the shortest possible form. + * + * Populates `FuzzierSettings.state.modules`-field + */ + fun parseModules(project: Project) { + val moduleManager = ModuleManager.getInstance(project) + + // Gather all modules and paths into a list + val moduleList: MutableList = ArrayList() + for (module in moduleManager.modules) { + val modulePath = getModulePath(module) ?: continue + moduleList.add(ModuleContainer(module.name, modulePath)) + } - var prevModule: ModuleContainer? = null - for (currentModule in moduleList.sortedBy { it.basePath }) { - if (prevModule != null && (currentModule.basePath.startsWith(prevModule.basePath) - || prevModule.basePath.startsWith(currentModule.basePath)) - ) { - if (currentModule.basePath.length > prevModule.basePath.length) { - currentModule.basePath = prevModule.basePath - } else { - prevModule.basePath = currentModule.basePath + var prevModule: ModuleContainer? = null + for (currentModule in moduleList.sortedBy { it.basePath }) { + if (prevModule != null && (currentModule.basePath.startsWith(prevModule.basePath) + || prevModule.basePath.startsWith(currentModule.basePath)) + ) { + if (currentModule.basePath.length > prevModule.basePath.length) { + currentModule.basePath = prevModule.basePath + } else { + prevModule.basePath = currentModule.basePath + } } + + prevModule = currentModule } - prevModule = currentModule - } + if (moduleList.map { it.basePath }.distinct().size > 1) { + shortenModulePaths(moduleList) + } - if (moduleList.map { it.basePath }.distinct().size > 1) { - shortenModulePaths(moduleList) - } + if (moduleList.isEmpty() && project.basePath != null) { + moduleList.add(ModuleContainer(project.name, project.basePath!!)) + project.service().state.isProject = true + } - if (moduleList.isEmpty() && project.basePath != null) { - moduleList.add(ModuleContainer(project.name, project.basePath!!)) - project.service().state.isProject = true + val moduleMap = listToMap(moduleList) + project.service().state.modules = moduleMap } - val moduleMap = listToMap(moduleList) - project.service().state.modules = moduleMap - } + private fun shortenModulePaths(modules: List) { + for (module in modules) { + module.basePath = module.basePath.substringBeforeLast("/") + } + } - private fun shortenModulePaths(modules: List) { - for (module in modules) { - module.basePath = module.basePath.substringBeforeLast("/") + private fun getModulePath(module: Module): String? { + val contentRoots = module.rootManager.contentRoots + if (contentRoots.isEmpty()) { + return null + } + return contentRoots.firstOrNull()?.path } - } - private fun getModulePath(module: Module): String? { - val contentRoots = module.rootManager.contentRoots - if (contentRoots.isEmpty()) { - return null + private fun listToMap(modules: List): Map { + return modules.associateBy({ it.name }, { it.basePath }) } - return contentRoots.firstOrNull()?.path } data class ModuleContainer(val name: String, var basePath: String) - - private fun listToMap(modules: List): Map { - return modules.associateBy({ it.name }, { it.basePath }) - } } \ No newline at end of file diff --git a/src/main/kotlin/com/mituuz/fuzzier/util/InitialViewHandler.kt b/src/main/kotlin/com/mituuz/fuzzier/util/InitialViewHandler.kt deleted file mode 100644 index b9ece779..00000000 --- a/src/main/kotlin/com/mituuz/fuzzier/util/InitialViewHandler.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* -MIT License - -Copyright (c) 2025 Mitja Leino - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -package com.mituuz.fuzzier.util - -import com.intellij.openapi.fileEditor.impl.EditorHistoryManager -import com.intellij.openapi.project.Project -import com.mituuz.fuzzier.entities.FuzzyContainer -import com.mituuz.fuzzier.entities.FuzzyMatchContainer -import com.mituuz.fuzzier.entities.OrderedContainer -import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService -import com.mituuz.fuzzier.settings.FuzzierSettingsService -import javax.swing.DefaultListModel - -class InitialViewHandler { - companion object { - fun getRecentProjectFiles( - globalState: FuzzierGlobalSettingsService.State, fuzzierUtil: FuzzierUtil, - editorHistoryManager: EditorHistoryManager, - project: Project - ): DefaultListModel { - val editorHistory = editorHistoryManager.fileList - val listModel = DefaultListModel() - val limit = globalState.fileListLimit - - // Start from the end of editor history (most recent file) - var i = editorHistory.size - 1 - while (i >= 0 && listModel.size() < limit) { - val file = editorHistory[i] - val filePathAndModule = fuzzierUtil.extractModulePath(file.path, project) - // Don't add files that do not have a module path in the project - if (filePathAndModule.second == "") { - i-- - continue - } - val orderedContainer = OrderedContainer( - filePathAndModule.first, filePathAndModule.second, file.name - ) - listModel.addElement(orderedContainer) - i-- - } - - return listModel - } - - fun getRecentlySearchedFiles(projectState: FuzzierSettingsService.State): DefaultListModel { - var listModel = projectState.getRecentlySearchedFilesAsFuzzyMatchContainer() - - var i = 0 - while (i < listModel.size) { - if (listModel[i] == null) { - listModel.remove(i) - } else { - i++ - } - } - - // Reverse the list to show the most recent searches first - var result = DefaultListModel() - - var j = 0 - while (j < listModel.size) { - val index = listModel.size - j - 1 - result.addElement(listModel[index]) - j++ - } - - return result - } - - fun addFileToRecentlySearchedFiles(fuzzyContainer: FuzzyContainer, projectState: FuzzierSettingsService.State, - globalState: FuzzierGlobalSettingsService.State) { - var listModel: DefaultListModel = projectState.getRecentlySearchedFilesAsFuzzyMatchContainer() - - var i = 0 - while (i < listModel.size) { - if (listModel[i].filePath == fuzzyContainer.filePath) { - listModel.remove(i) - } else { - i++ - } - } - - while (listModel.size > globalState.fileListLimit - 1) { - listModel.remove(listModel.size - 1) - } - - if (fuzzyContainer is FuzzyMatchContainer) { - listModel.addElement(fuzzyContainer) - projectState.recentlySearchedFiles = FuzzyMatchContainer.SerializedMatchContainer.fromListModel(listModel) - } - } - } -} \ No newline at end of file diff --git a/src/test/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProviderTest.kt b/src/test/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProviderTest.kt new file mode 100644 index 00000000..805240b9 --- /dev/null +++ b/src/test/kotlin/com/mituuz/fuzzier/search/initialview/OpenTabsInitialListModelProviderTest.kt @@ -0,0 +1,117 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.intellij.openapi.vfs.VirtualFile +import io.mockk.every +import io.mockk.mockk +import io.mockk.unmockkAll +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +class OpenTabsInitialListModelProviderTest { + @AfterEach + fun tearDown() { + unmockkAll() + } + + @Test + fun `buildInitialView with no open files`() { + val provider = OpenTabsInitialListModelProvider(emptyMap(), emptyArray()) + val model = provider.invoke() + assertEquals(0, model.size()) + } + + @Test + fun `buildInitialView with multiple open files`() { + val file1 = mockk() + val file2 = mockk() + + every { file1.isDirectory } returns false + every { file1.path } returns "/project/src/File1.kt" + every { file1.name } returns "File1.kt" + + every { file2.isDirectory } returns false + every { file2.path } returns "/project/src/File2.kt" + every { file2.name } returns "File2.kt" + + val modules = mapOf("project" to "/project/") + val provider = OpenTabsInitialListModelProvider(modules, arrayOf(file1, file2)) + + val model = provider.invoke() + + assertEquals(2, model.size()) + // Should be in reverse order of openFiles + assertEquals("File2.kt", model.get(0).filename) + assertEquals("src/File2.kt", model.get(0).filePath) + assertEquals("File1.kt", model.get(1).filename) + assertEquals("src/File1.kt", model.get(1).filePath) + } + + @Test + fun `buildInitialView excludes directories`() { + val file1 = mockk() + val dir1 = mockk() + + every { file1.isDirectory } returns false + every { file1.path } returns "/project/src/File1.kt" + every { file1.name } returns "File1.kt" + + every { dir1.isDirectory } returns true + every { dir1.path } returns "/project/src/dir" + every { dir1.name } returns "dir" + + val modules = mapOf("project" to "/project/") + val provider = OpenTabsInitialListModelProvider(modules, arrayOf(file1, dir1)) + + val model = provider.invoke() + + assertEquals(1, model.size()) + assertEquals("File1.kt", model.get(0).filename) + } + + @Test + fun `buildInitialView excludes files without module path`() { + val file1 = mockk() + val fileOutside = mockk() + + every { file1.isDirectory } returns false + every { file1.path } returns "/project/src/File1.kt" + every { file1.name } returns "File1.kt" + + every { fileOutside.isDirectory } returns false + every { fileOutside.path } returns "/outside/File.kt" + every { fileOutside.name } returns "File.kt" + + val modules = mapOf("project" to "/project/") + val provider = OpenTabsInitialListModelProvider(modules, arrayOf(file1, fileOutside)) + + val model = provider.invoke() + + assertEquals(1, model.size()) + assertEquals("File1.kt", model.get(0).filename) + } +} diff --git a/src/test/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtilTest.kt b/src/test/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtilTest.kt new file mode 100644 index 00000000..d7ff4831 --- /dev/null +++ b/src/test/kotlin/com/mituuz/fuzzier/search/initialview/RecentlySearchedFilesUtilTest.kt @@ -0,0 +1,118 @@ +/* + * MIT License + * + * Copyright (c) 2025 Mitja Leino + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.mituuz.fuzzier.search.initialview + +import com.intellij.openapi.components.service +import com.intellij.testFramework.TestApplicationManager +import com.mituuz.fuzzier.entities.FuzzyMatchContainer +import com.mituuz.fuzzier.entities.FuzzyMatchContainer.FileType.FILE +import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService +import com.mituuz.fuzzier.settings.FuzzierSettingsService +import io.mockk.unmockkAll +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Test +import javax.swing.DefaultListModel + +class RecentlySearchedFilesUtilTest { + @Suppress("unused") // Required for add to recently used files (fuzzierSettingsServiceInstance) + private var testApplicationManager: TestApplicationManager = TestApplicationManager.getInstance() + + @AfterEach + fun tearDown() { + unmockkAll() + } + + @Test + fun `Add file to recently used files - Null list should default to empty`() { + val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() + val fgss = service().state + val score = FuzzyMatchContainer.FuzzyScore() + val container = FuzzyMatchContainer(score, "", "", "", FILE) + + fuzzierSettingsServiceInstance.state.recentlySearchedFiles = null + addFileToRecentlySearchedFiles( + container, + fuzzierSettingsServiceInstance.state, + fgss + ) + assertNotNull(fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer()) + assertEquals(1, fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size) + } + + @Test + fun `Add file to recently used files - Too large list is truncated`() { + val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() + val fgss = service().state + val fileListLimit = 2 + val score = FuzzyMatchContainer.FuzzyScore() + val container = FuzzyMatchContainer(score, "", "", "", FILE) + + val largeList: DefaultListModel = DefaultListModel() + for (i in 0..25) { + largeList.addElement(FuzzyMatchContainer(score, "" + i, "" + i, "", FILE)) + } + + fgss.fileListLimit = fileListLimit + + fuzzierSettingsServiceInstance.state.recentlySearchedFiles = + FuzzyMatchContainer.SerializedMatchContainer.fromListModel(largeList) + addFileToRecentlySearchedFiles( + container, + fuzzierSettingsServiceInstance.state, + fgss + ) + assertEquals( + fileListLimit, + fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size + ) + } + + @Test + fun `Add file to recently used files - Duplicate filenames are removed`() { + val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() + val fgss = service().state + val fileListLimit = 20 + val score = FuzzyMatchContainer.FuzzyScore() + val container = FuzzyMatchContainer(score, "", "", "", FILE) + + val largeList: DefaultListModel = DefaultListModel() + repeat(26) { + largeList.addElement(FuzzyMatchContainer(score, "", "", "", FILE)) + } + + fgss.fileListLimit = fileListLimit + + fuzzierSettingsServiceInstance.state.recentlySearchedFiles = + FuzzyMatchContainer.SerializedMatchContainer.fromListModel(largeList) + addFileToRecentlySearchedFiles( + container, + fuzzierSettingsServiceInstance.state, + fgss + ) + assertEquals(1, fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size) + } +} diff --git a/src/test/kotlin/com/mituuz/fuzzier/util/InitialViewHandlerTest.kt b/src/test/kotlin/com/mituuz/fuzzier/util/DefaultInitialListModelProviderTest.kt similarity index 51% rename from src/test/kotlin/com/mituuz/fuzzier/util/InitialViewHandlerTest.kt rename to src/test/kotlin/com/mituuz/fuzzier/util/DefaultInitialListModelProviderTest.kt index 5e83e23f..dec7861e 100644 --- a/src/test/kotlin/com/mituuz/fuzzier/util/InitialViewHandlerTest.kt +++ b/src/test/kotlin/com/mituuz/fuzzier/util/DefaultInitialListModelProviderTest.kt @@ -23,30 +23,31 @@ */ package com.mituuz.fuzzier.util -import com.intellij.openapi.components.service import com.intellij.openapi.fileEditor.impl.EditorHistoryManager import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import com.intellij.testFramework.TestApplicationManager import com.mituuz.fuzzier.entities.FuzzyMatchContainer -import com.mituuz.fuzzier.entities.FuzzyMatchContainer.FileType.FILE +import com.mituuz.fuzzier.search.initialview.DefaultInitialListModelProvider import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService import com.mituuz.fuzzier.settings.FuzzierSettingsService import com.mituuz.fuzzier.settings.FuzzierSettingsService.State import io.mockk.every import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.unmockkAll +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import javax.swing.DefaultListModel -class InitialViewHandlerTest { +class DefaultInitialListModelProviderTest { private lateinit var project: Project private lateinit var fuzzierSettingsService: FuzzierSettingsService private lateinit var fuzzierGlobalSettingsService: FuzzierGlobalSettingsService private lateinit var fuzzierUtil: FuzzierUtil - private lateinit var initialViewHandler: InitialViewHandler + private lateinit var defaultInitialListModelProvider: DefaultInitialListModelProvider private lateinit var state: State private lateinit var editorHistoryManager: EditorHistoryManager @@ -59,12 +60,18 @@ class InitialViewHandlerTest { fuzzierSettingsService = mockk() fuzzierGlobalSettingsService = mockk() state = mockk() - fuzzierUtil = mockk() - initialViewHandler = InitialViewHandler() + val globalState = FuzzierGlobalSettingsService.State() + globalState.recentFilesMode = FuzzierGlobalSettingsService.RecentFilesMode.RECENT_PROJECT_FILES + defaultInitialListModelProvider = DefaultInitialListModelProvider(project, globalState, state) editorHistoryManager = mockk() every { fuzzierSettingsService.state } returns state } + @AfterEach + fun tearDown() { + unmockkAll() + } + @Test fun `Recent project files - Verify that list is truncated when it goes over the file limit`() { val virtualFile1 = mockk() @@ -73,15 +80,22 @@ class InitialViewHandlerTest { virtualFile1, virtualFile2 ) - val fgss = service().state + mockkStatic(EditorHistoryManager::class) + every { EditorHistoryManager.getInstance(project) } returns editorHistoryManager every { editorHistoryManager.fileList } returns fileList + val fgss = defaultInitialListModelProvider.globalState fgss.fileListLimit = 1 - every { virtualFile1.path } returns "path" + every { virtualFile1.path } returns "/project/path/file1" every { virtualFile1.name } returns "filename1" - every { virtualFile2.path } returns "path" + every { virtualFile2.path } returns "/project/path/file2" every { virtualFile2.name } returns "filename2" - every { fuzzierUtil.extractModulePath(any(), project) } returns Pair("path", "module") - val result = InitialViewHandler.getRecentProjectFiles(fgss, fuzzierUtil, editorHistoryManager, project) + + val settingsState = FuzzierSettingsService.State() + settingsState.modules = mapOf("module" to "/project/path/") + defaultInitialListModelProvider = DefaultInitialListModelProvider(project, fgss, settingsState) + + val result = + defaultInitialListModelProvider.getRecentProjectFiles(project) assertEquals(1, result.size()) } @@ -94,26 +108,36 @@ class InitialViewHandlerTest { virtualFile1, virtualFile2 ) - val fgss = service().state + mockkStatic(EditorHistoryManager::class) + every { EditorHistoryManager.getInstance(project) } returns editorHistoryManager every { editorHistoryManager.fileList } returns fileList + val fgss = defaultInitialListModelProvider.globalState fgss.fileListLimit = 2 - every { virtualFile1.path } returns "path" + every { virtualFile1.path } returns "/project/path/file1" every { virtualFile1.name } returns "filename1" - every { virtualFile2.path } returns "path" + every { virtualFile2.path } returns "/other/path/file2" every { virtualFile2.name } returns "filename2" - every { fuzzierUtil.extractModulePath(any(), project) } returns Pair("path", "module") andThen Pair("", "") - val result = InitialViewHandler.getRecentProjectFiles(fgss, fuzzierUtil, editorHistoryManager, project) + + val settingsState = FuzzierSettingsService.State() + settingsState.modules = mapOf("module" to "/project/path/") + defaultInitialListModelProvider = DefaultInitialListModelProvider(project, fgss, settingsState) + + val result = + defaultInitialListModelProvider.getRecentProjectFiles(project) assertEquals(1, result.size()) } @Test fun `Recent project files - Empty list when no history`() { - val fgss = service().state + mockkStatic(EditorHistoryManager::class) + every { EditorHistoryManager.getInstance(project) } returns editorHistoryManager + val fgss = defaultInitialListModelProvider.globalState every { editorHistoryManager.fileList } returns emptyList() fgss.fileListLimit = 2 - val result = InitialViewHandler.getRecentProjectFiles(fgss, fuzzierUtil, editorHistoryManager, project) + val result = + defaultInitialListModelProvider.getRecentProjectFiles(project) assertEquals(0, result.size()) } @@ -125,9 +149,9 @@ class InitialViewHandlerTest { val listModel = DefaultListModel() listModel.addElement(fuzzyMatchContainer1) listModel.addElement(fuzzyMatchContainer2) - every { fuzzierSettingsService.state.getRecentlySearchedFilesAsFuzzyMatchContainer() } returns listModel + every { state.getRecentlySearchedFilesAsFuzzyMatchContainer() } returns listModel - val result = InitialViewHandler.getRecentlySearchedFiles(fuzzierSettingsService.state) + val result = defaultInitialListModelProvider.getRecentlySearchedFiles() assertEquals(fuzzyMatchContainer2, result[0]) assertEquals(fuzzyMatchContainer1, result[1]) @@ -140,68 +164,10 @@ class InitialViewHandlerTest { listModel.addElement(fuzzyMatchContainer) listModel.addElement(null) listModel.addElement(null) - every { fuzzierSettingsService.state.getRecentlySearchedFilesAsFuzzyMatchContainer() } returns listModel + every { state.getRecentlySearchedFilesAsFuzzyMatchContainer() } returns listModel - val result = InitialViewHandler.getRecentlySearchedFiles(fuzzierSettingsService.state) + val result = defaultInitialListModelProvider.getRecentlySearchedFiles() assertEquals(1, result.size) } - - @Test - fun `Add file to recently used files - Null list should default to empty`() { - val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() - val fgss = service().state - val score = FuzzyMatchContainer.FuzzyScore() - val container = FuzzyMatchContainer(score, "", "", "", FILE) - - fuzzierSettingsServiceInstance.state.recentlySearchedFiles = null - InitialViewHandler.addFileToRecentlySearchedFiles(container, fuzzierSettingsServiceInstance.state, fgss) - assertNotNull(fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer()) - assertEquals(1, fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size) - } - - @Test - fun `Add file to recently used files - Too large list is truncated`() { - val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() - val fgss = service().state - val fileListLimit = 2 - val score = FuzzyMatchContainer.FuzzyScore() - val container = FuzzyMatchContainer(score, "", "", "", FILE) - - val largeList: DefaultListModel = DefaultListModel() - for (i in 0..25) { - largeList.addElement(FuzzyMatchContainer(score, "" + i, "" + i, "", FILE)) - } - - fgss.fileListLimit = fileListLimit - - fuzzierSettingsServiceInstance.state.recentlySearchedFiles = - FuzzyMatchContainer.SerializedMatchContainer.fromListModel(largeList) - InitialViewHandler.addFileToRecentlySearchedFiles(container, fuzzierSettingsServiceInstance.state, fgss) - assertEquals( - fileListLimit, - fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size - ) - } - - @Test - fun `Add file to recently used files - Duplicate filenames are removed`() { - val fuzzierSettingsServiceInstance: FuzzierSettingsService = service() - val fgss = service().state - val fileListLimit = 20 - val score = FuzzyMatchContainer.FuzzyScore() - val container = FuzzyMatchContainer(score, "", "", "", FILE) - - val largeList: DefaultListModel = DefaultListModel() - repeat(26) { - largeList.addElement(FuzzyMatchContainer(score, "", "", "", FILE)) - } - - fgss.fileListLimit = fileListLimit - - fuzzierSettingsServiceInstance.state.recentlySearchedFiles = - FuzzyMatchContainer.SerializedMatchContainer.fromListModel(largeList) - InitialViewHandler.addFileToRecentlySearchedFiles(container, fuzzierSettingsServiceInstance.state, fgss) - assertEquals(1, fuzzierSettingsServiceInstance.state.getRecentlySearchedFilesAsFuzzyMatchContainer().size) - } } \ No newline at end of file diff --git a/src/test/kotlin/com/mituuz/fuzzier/util/FuzzierUtilTest.kt b/src/test/kotlin/com/mituuz/fuzzier/util/FuzzierUtilTest.kt index ae48d384..41cbef4e 100644 --- a/src/test/kotlin/com/mituuz/fuzzier/util/FuzzierUtilTest.kt +++ b/src/test/kotlin/com/mituuz/fuzzier/util/FuzzierUtilTest.kt @@ -36,7 +36,6 @@ import javax.swing.DefaultListModel class FuzzierUtilTest { @Suppress("unused") private val testApplicationManager = TestApplicationManager.getInstance() - private val fuzzierUtil = FuzzierUtil() private val listModel = DefaultListModel() private val testUtil = TestUtil() @@ -52,7 +51,7 @@ class FuzzierUtilTest { listOf("src2", "/src2/file2"), listOf("src3", "/src3/file3") ) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules assertEquals(3, modules.size) @@ -69,7 +68,7 @@ class FuzzierUtilTest { listOf("to/src2", "/to/src2/file2"), listOf("module/src3", "/module/src3/file3") ) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules assertEquals(3, modules.size) @@ -87,7 +86,7 @@ class FuzzierUtilTest { listOf("src1/module1", "/src1/module1/file1"), listOf("src1/module2", "/src1/module2/file1") ) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules @@ -104,24 +103,24 @@ class FuzzierUtilTest { listOf("src1/module1", "/src1/module1/file1"), listOf("src2", "/src2/file1") ) val project = myFixture.project - fuzzierUtil.parseModules(project) + FuzzierUtil.parseModules(project) val modules = myFixture.project.service().state.modules assertEquals(3, modules.size) var file = myFixture.findFileInTempDir("/src1/file1") - assertEquals("/src1/file1", fuzzierUtil.extractModulePath(file.path, project).first) - var finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src1/file1", FuzzierUtil.extractModulePath(file.path, modules).first) + var finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("unitTest")) file = myFixture.findFileInTempDir("/src1/module1/file1") - assertEquals("/src1/module1/file1", fuzzierUtil.extractModulePath(file.path, project).first) - finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src1/module1/file1", FuzzierUtil.extractModulePath(file.path, modules).first) + finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("unitTest")) file = myFixture.findFileInTempDir("/src2/file1") - assertEquals("/src2/file1", fuzzierUtil.extractModulePath(file.path, project).first) - finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src2/file1", FuzzierUtil.extractModulePath(file.path, modules).first) + finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("unitTest")) } @@ -133,54 +132,54 @@ class FuzzierUtilTest { listOf("module/src3", "/module/src3/file3") ) val project = myFixture.project - fuzzierUtil.parseModules(project) + FuzzierUtil.parseModules(project) val modules = myFixture.project.service().state.modules assertEquals(3, modules.size) var file = myFixture.findFileInTempDir("/path/src1/file1") - assertEquals("/src1/file1", fuzzierUtil.extractModulePath(file.path, project).first) - var finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src1/file1", FuzzierUtil.extractModulePath(file.path, modules).first) + var finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("path")) file = myFixture.findFileInTempDir("/to/src2/file2") - assertEquals("/src2/file2", fuzzierUtil.extractModulePath(file.path, project).first) - finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src2/file2", FuzzierUtil.extractModulePath(file.path, modules).first) + finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("to")) file = myFixture.findFileInTempDir("/module/src3/file3") - assertEquals("/src3/file3", fuzzierUtil.extractModulePath(file.path, project).first) - finalPath = fuzzierUtil.extractModulePath(file.path, project).second.substringAfterLast("/") + assertEquals("/src3/file3", FuzzierUtil.extractModulePath(file.path, modules).first) + finalPath = FuzzierUtil.extractModulePath(file.path, modules).second.substringAfterLast("/") assertTrue(finalPath.startsWith("module")) } @Test fun `Remove module paths, point only to project root`() { val myFixture = testUtil.setUpMultiModuleProject(listOf("path/src1", "/path/src1/file1")) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules assertEquals(1, modules.size) val file = myFixture.findFileInTempDir("/path/src1/file1") - assertEquals("/file1", fuzzierUtil.extractModulePath(file.path, myFixture.project).first) + assertEquals("/file1", FuzzierUtil.extractModulePath(file.path, modules).first) } @Test fun `Remove module paths, file not included`() { val myFixture = testUtil.setUpMultiModuleProject(listOf("path/src1", "/path/src1/file1")) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules assertEquals(1, modules.size) - assertEquals(Pair("/no/such/file", ""), fuzzierUtil.extractModulePath("/no/such/file", myFixture.project)) + assertEquals(Pair("/no/such/file", ""), FuzzierUtil.extractModulePath("/no/such/file", modules)) } @Test fun parseModulesSingleModule() { val myFixture = testUtil.setUpMultiModuleProject(listOf("src1", "/src1/file1")) - fuzzierUtil.parseModules(myFixture.project) + FuzzierUtil.parseModules(myFixture.project) val modules = myFixture.project.service().state.modules assertEquals(1, modules.size)