Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions src/main/kotlin/com/mituuz/fuzzier/grep/FuzzyGrep.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ open class FuzzyGrep : FuzzyAction() {

val projectBasePath = project.basePath.toString()
currentLaunchJob = actionScope?.launch(Dispatchers.EDT) {
val backendResult: Result<BackendStrategy> = withContext(Dispatchers.IO) {
backendResolver.resolveBackend(commandRunner, projectBasePath)
}
val backendResult: Result<BackendStrategy> = backendResolver.resolveBackend(commandRunner, projectBasePath)
if (backendResult.isFailure) {
showNotification(
"No search command found", "Fuzzy Grep failed: no suitable grep command found", project
Expand All @@ -92,7 +90,7 @@ open class FuzzyGrep : FuzzyAction() {
}

val resolvedBackend = backendResult.getOrNull() ?: return@launch
updateBackend(resolvedBackend)
backend = resolvedBackend
val popupTitle = grepConfig.getPopupTitle(resolvedBackend.name)

yield()
Expand Down Expand Up @@ -149,7 +147,8 @@ open class FuzzyGrep : FuzzyAction() {
searchString,
project,
changelistManager,
backend
backend,
(component as FuzzyFinderComponent),
)
coroutineContext.ensureActive()

Expand All @@ -170,13 +169,14 @@ open class FuzzyGrep : FuzzyAction() {
searchString: String,
project: Project,
clm: ChangeListManager,
resolvedBackend: BackendStrategy?
resolvedBackend: BackendStrategy?,
fuzzyFinderComponent: FuzzyFinderComponent,
): ListModel<FuzzyContainer> {
val listModel = DefaultListModel<FuzzyContainer>()
val projectBasePath = project.basePath

if (resolvedBackend != null && projectBasePath != null) {
val secondaryFieldText = (component as FuzzyFinderComponent).getSecondaryText()
val secondaryFieldText = fuzzyFinderComponent.getSecondaryText()
resolvedBackend.handleSearch(
grepConfig, searchString, secondaryFieldText, commandRunner, listModel, projectBasePath, project
) { vf ->
Expand Down Expand Up @@ -240,10 +240,6 @@ open class FuzzyGrep : FuzzyAction() {
}
}

fun updateBackend(resolvedBackend: BackendStrategy?) {
backend = resolvedBackend
}

fun updateGrepConfig(config: GrepConfig) {
grepConfig = config
}
Expand Down
19 changes: 11 additions & 8 deletions src/main/kotlin/com/mituuz/fuzzier/grep/backend/BackendResolver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,22 @@ import com.intellij.openapi.components.service
import com.mituuz.fuzzier.runner.CommandRunner
import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService
import com.mituuz.fuzzier.settings.FuzzierGlobalSettingsService.GrepBackend
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class BackendResolver(val isWindows: Boolean) {
suspend fun resolveBackend(commandRunner: CommandRunner, projectBasePath: String): Result<BackendStrategy> {
val grepBackendSetting = service<FuzzierGlobalSettingsService>().state.grepBackend
suspend fun resolveBackend(commandRunner: CommandRunner, projectBasePath: String): Result<BackendStrategy> =
withContext(Dispatchers.IO) {
val grepBackendSetting = service<FuzzierGlobalSettingsService>().state.grepBackend

return when (grepBackendSetting) {
GrepBackend.FUZZIER -> Result.success(FuzzierGrep)
GrepBackend.DYNAMIC -> when {
isInstalled(commandRunner, "rg", projectBasePath) -> Result.success(Ripgrep)
else -> Result.success(FuzzierGrep)
when (grepBackendSetting) {
GrepBackend.FUZZIER -> Result.success(FuzzierGrep)
GrepBackend.DYNAMIC -> when {
isInstalled(commandRunner, "rg", projectBasePath) -> Result.success(Ripgrep)
else -> Result.success(FuzzierGrep)
}
}
}
}

private suspend fun isInstalled(
commandRunner: CommandRunner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import com.mituuz.fuzzier.entities.GrepConfig
import com.mituuz.fuzzier.runner.CommandRunner
import javax.swing.DefaultListModel

sealed interface BackendStrategy {
interface BackendStrategy {
val name: String

suspend fun handleSearch(
Expand Down
72 changes: 54 additions & 18 deletions src/test/kotlin/com/mituuz/fuzzier/grep/FuzzyGrepTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,30 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.TestApplicationManager
import com.mituuz.fuzzier.components.FuzzyFinderComponent
import com.mituuz.fuzzier.entities.CaseMode
import com.mituuz.fuzzier.entities.FuzzyContainer
import com.mituuz.fuzzier.entities.GrepConfig
import com.mituuz.fuzzier.grep.backend.BackendStrategy
import com.mituuz.fuzzier.runner.CommandRunner
import io.mockk.every
import io.mockk.mockk
import io.mockk.unmockkAll
import kotlinx.coroutines.runBlocking
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.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import javax.swing.DefaultListModel

class FuzzyGrepTest {
private lateinit var fGrep: FuzzyGrep

private data class ValidVfContext(
val file: VirtualFile,
val clm: ChangeListManager
val file: VirtualFile, val clm: ChangeListManager
)

private data class FindInFilesContext(
val project: Project,
val component: FuzzyFinderComponent,
val backend: BackendStrategy,
val clm: ChangeListManager
)

Expand All @@ -69,10 +69,7 @@ class FuzzyGrepTest {
}

private fun createValidVfContext(
isDirectory: Boolean = false,
isBinary: Boolean = false,
isIgnored: Boolean = false,
extension: String? = null
isDirectory: Boolean = false, isBinary: Boolean = false, isIgnored: Boolean = false, extension: String? = null
): ValidVfContext {
val file = mockk<VirtualFile>()
val clm = mockk<ChangeListManager>()
Expand All @@ -88,24 +85,21 @@ class FuzzyGrepTest {
}

private fun createFindInFilesContext(
projectBasePath: String? = "/tmp/project",
secondaryText: String = "kt"
projectBasePath: String? = "/tmp/project", secondaryText: String = "kt"
): FindInFilesContext {
val project = mockk<Project>()
val component = mockk<FuzzyFinderComponent>()
val backend = mockk<BackendStrategy>()
val clm = mockk<ChangeListManager>()

every { project.basePath } returns projectBasePath
every { component.getSecondaryText() } returns secondaryText

fGrep.component = component
fGrep.updateBackend(backend)
fGrep.updateGrepConfig(
GrepConfig(targets = null, caseMode = CaseMode.SENSITIVE, title = "Fuzzy Grep")
)

return FindInFilesContext(project, component, backend, clm)
return FindInFilesContext(project, component, clm)
}

@Test
Expand Down Expand Up @@ -158,21 +152,63 @@ class FuzzyGrepTest {

@Test
fun `findInFiles should skip backend when backend is null`() = runBlocking {
val (project, _, _, clm) = createFindInFilesContext()
val (project, component, clm) = createFindInFilesContext()

val model = fGrep.findInFiles("needle", project, clm, null)
val model = fGrep.findInFiles("needle", project, clm, null, component)

assertNotNull(model)
assertEquals(0, model.size)
}

@Test
fun `findInFiles should skip backend when project base path is null`() = runBlocking {
val (project, _, backend, clm) = createFindInFilesContext(projectBasePath = null)
val (project, component, clm) = createFindInFilesContext(projectBasePath = null)
val backend = MockBackend()

val model = fGrep.findInFiles("needle", project, clm, backend)
val model = fGrep.findInFiles("needle", project, clm, backend, component)

assertNotNull(model)
assertEquals(0, model.size)
assertFalse(backend.wasCalled)
}

@Test
fun `findInFiles calls backend when backend and project base path are available`() = runBlocking {
val (project, component, clm) = createFindInFilesContext(projectBasePath = "not/null")
val backend = MockBackend()

val model = fGrep.findInFiles("needle", project, clm, backend, component)

assertNotNull(model)
assertEquals(0, model.size)
assertTrue(backend.wasCalled)
assertEquals("needle", backend.receivedSearchString)
assertEquals("kt", backend.receivedSecondarySearchString)
assertEquals("not/null", backend.receivedProjectBasePath)
}

private class MockBackend : BackendStrategy {
override val name: String = "Mock"

var wasCalled = false
var receivedSearchString: String? = null
var receivedSecondarySearchString: String? = null
var receivedProjectBasePath: String? = null

override suspend fun handleSearch(
grepConfig: GrepConfig,
searchString: String,
secondarySearchString: String?,
commandRunner: CommandRunner,
listModel: DefaultListModel<FuzzyContainer>,
projectBasePath: String,
project: Project,
fileFilter: (VirtualFile) -> Boolean
) {
wasCalled = true
receivedSearchString = searchString
receivedSecondarySearchString = secondarySearchString
receivedProjectBasePath = projectBasePath
}
}
}
Loading