diff --git a/app/src/main/assets/data/common/tooling-api-all.jar b/app/src/main/assets/data/common/tooling-api-all.jar index 070c0d94d..b9834437a 100644 Binary files a/app/src/main/assets/data/common/tooling-api-all.jar and b/app/src/main/assets/data/common/tooling-api-all.jar differ diff --git a/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/editor/DocumentEvents.kt b/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/editor/DocumentEvents.kt index f4576263e..a5b74a645 100644 --- a/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/editor/DocumentEvents.kt +++ b/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/editor/DocumentEvents.kt @@ -45,7 +45,7 @@ constructor(var closedFile: Path, val selectionRange: Range = Range.NONE) : data class DocumentChangeEvent( var changedFile: Path, var changedText: String, - var newText: String?, + var newText: String? = null, var version: Int, var changeType: ChangeType, var changeDelta: Int, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ec7937ea..e8d58aec8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -98,6 +98,7 @@ tests-androidx-test-core = { module = "androidx.test:core", version = "1.5.0" } tests-androidx-junit = { module = "androidx.test.ext:junit", version = "1.1.5" } tests-androidx-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" } tests-mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "4.1.0" } +tests-mockk = { module = "io.mockk:mockk", version = "1.13.4" } # Tooling tooling-builderModel = { module="com.android.tools.build:builder-model", version.ref = "agp-tooling" } diff --git a/lsp/api/src/main/java/com/itsaky/androidide/lsp/snippets/SnippetParser.kt b/lsp/api/src/main/java/com/itsaky/androidide/lsp/snippets/SnippetParser.kt index ce69c3493..fc619b5bc 100644 --- a/lsp/api/src/main/java/com/itsaky/androidide/lsp/snippets/SnippetParser.kt +++ b/lsp/api/src/main/java/com/itsaky/androidide/lsp/snippets/SnippetParser.kt @@ -22,6 +22,7 @@ import com.google.gson.stream.JsonReader import com.itsaky.androidide.app.BaseApplication import com.itsaky.androidide.tasks.executeAsyncProvideError import com.itsaky.androidide.utils.ILogger +import com.itsaky.androidide.utils.VMUtils import java.io.IOException import java.util.concurrent.ConcurrentHashMap @@ -41,6 +42,12 @@ object SnippetParser { DefaultSnippet(prefix, desc, body.toTypedArray()) } ): Map> { + + // not supported for tests as assets cannot be accessed + if (VMUtils.isJvm()) { + return emptyMap() + } + return ConcurrentHashMap>().apply { for (scope in scopes) { this[scope] = @@ -62,7 +69,7 @@ object SnippetParser { try { BaseApplication.getBaseInstance() .assets - .open("data/editor/${lang}/snippets.${type}.json") + .open(assetsPath(lang, type)) .reader() } catch (e: IOException) { // snippet file probably does not exist @@ -84,6 +91,9 @@ object SnippetParser { } } + fun assetsPath(lang: String, type: String) = + "data/editor/${lang}/snippets.${type}.json" + private fun readSnippet( prefix: String, reader: JsonReader, diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt index 8d682a06f..1494e7567 100644 --- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt +++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/partial/PartialReparserImplTest.kt @@ -79,6 +79,7 @@ class PartialReparserImplTest { DocumentChangeEvent( file!!, contents!!.insert(192, "trim().").toString(), + null, 2, INSERT, "trim().".length, diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProviderTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProviderTest.kt index 8b5ff708a..0fb0145e5 100644 --- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProviderTest.kt +++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/providers/JavaSelectionProviderTest.kt @@ -41,7 +41,7 @@ class JavaSelectionProviderTest { openFile("selection/SimpleSelectionExpansionTest") cursor = requireCursor() deleteCursorText() - dispatchEvent(DocumentChangeEvent(file!!, contents.toString(), 1, NEW_TEXT, 0, Range.NONE)) + dispatchEvent(DocumentChangeEvent(file!!, contents.toString(), null,1, NEW_TEXT, 0, Range.NONE)) val range = findRange() val expanded = server.expandSelection(ExpandSelectionParams(file!!, range)) diff --git a/lsp/testing/build.gradle.kts b/lsp/testing/build.gradle.kts index 2b031874b..d8836f0f2 100644 --- a/lsp/testing/build.gradle.kts +++ b/lsp/testing/build.gradle.kts @@ -37,5 +37,6 @@ dependencies { implementation(libs.tests.junit) implementation(libs.tests.google.truth) implementation(libs.tests.robolectric) + implementation(libs.tests.mockk) implementation(projects.actions) } \ No newline at end of file diff --git a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt b/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt index 707d7f4ea..3de23a122 100644 --- a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt +++ b/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt @@ -20,13 +20,15 @@ package com.itsaky.androidide.lsp.api import android.content.Context import com.google.common.truth.Truth.assertThat import com.itsaky.androidide.actions.ActionData +import com.itsaky.androidide.app.BaseApplication import com.itsaky.androidide.eventbus.events.editor.ChangeType.DELETE import com.itsaky.androidide.eventbus.events.editor.DocumentChangeEvent import com.itsaky.androidide.eventbus.events.editor.DocumentOpenEvent import com.itsaky.androidide.lookup.Lookup +import com.itsaky.androidide.lsp.snippets.SnippetParser import com.itsaky.androidide.models.Position import com.itsaky.androidide.models.Range -import com.itsaky.androidide.projects.FileManager +import com.itsaky.androidide.preferences.internal.tabSize import com.itsaky.androidide.projects.ProjectManager import com.itsaky.androidide.projects.builder.BuildService import com.itsaky.androidide.tooling.api.IProject @@ -37,15 +39,18 @@ import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher.MultiVersion import com.itsaky.androidide.utils.Environment import com.itsaky.androidide.utils.ILogger import io.github.rosemoe.sora.text.Content -import java.io.File -import java.nio.file.Path -import kotlin.io.path.pathString +import io.mockk.every +import io.mockk.mockkStatic import org.greenrobot.eventbus.EventBus import org.junit.Before import org.junit.runner.RunWith +import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config +import java.io.File +import java.nio.file.Path +import kotlin.io.path.pathString /** * Runs tests for a language server. @@ -75,11 +80,18 @@ abstract class LSPTest { return } + mockkStatic(::tabSize) + every { tabSize } returns 4 + val (server, project) = - ToolingApiTestLauncher().launchServer(implDir = FileProvider.implModule().pathString, client = MultiVersionTestClient()) + ToolingApiTestLauncher() + .launchServer( + implDir = FileProvider.implModule().pathString, + client = MultiVersionTestClient() + ) this.toolingProject = project this.toolingServer = server - + Lookup.DEFAULT.update(BuildService.KEY_PROJECT_PROXY, project) server @@ -117,7 +129,7 @@ abstract class LSPTest { // As the content has been changed, we have to // Update the content in language server - dispatchEvent(DocumentChangeEvent(file!!, contents.toString(), 1, DELETE, 0, Range.NONE)) + dispatchEvent(DocumentChangeEvent(file!!, contents.toString(), null, 1, DELETE, 0, Range.NONE)) } @JvmOverloads diff --git a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/models/ActiveDocumentTest.kt b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/models/ActiveDocumentTest.kt deleted file mode 100644 index 9db8f2e27..000000000 --- a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/models/ActiveDocumentTest.kt +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of AndroidIDE. - * - * AndroidIDE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AndroidIDE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with AndroidIDE. If not, see . - */ - -package com.itsaky.androidide.projects.models - -import com.google.common.truth.Truth.assertThat -import com.itsaky.androidide.eventbus.events.editor.ChangeType -import com.itsaky.androidide.eventbus.events.editor.DocumentChangeEvent -import com.itsaky.androidide.models.Position -import com.itsaky.androidide.models.Range -import java.nio.file.Paths -import java.time.Instant -import org.junit.Test - -/** @author Akash Yadav */ -class ActiveDocumentTest { - - @Test - fun `test new text set patch`() { - val file = Paths.get("/") - val doc = ActiveDocument(file, 0, Instant.now(), "this is a string") - doc.patch( - DocumentChangeEvent( - file, - "this is a new text", - 2, - ChangeType.NEW_TEXT, - -1, - Range.pointRange(Position(0, doc.content.length).apply { index = column }) - ) - ) - - assertThat(doc.content).isEqualTo("this is a new text") - } - - @Test - fun `test single line insert patch`() { - val file = Paths.get("/") - val doc = ActiveDocument(file, 0, Instant.now(), "this is a string") - doc.patch( - DocumentChangeEvent( - file, - " added", - 2, - ChangeType.INSERT, - -1, - Range.pointRange(Position(0, doc.content.length).apply { index = column }) - ) - ) - - assertThat(doc.content).isEqualTo("this is a string added") - } - - @Test - fun `test single line delete patch`() { - val file = Paths.get("/") - val content = "this is a string added" - val doc = ActiveDocument(file, 0, Instant.now(), content) - doc.patch( - DocumentChangeEvent( - file, - " added", - 2, - ChangeType.DELETE, - -1, - Range( - Position(0, content.length - " added".length).apply { index = column }, - Position(0, content.length).apply { index = column } - ) - ) - ) - - assertThat(doc.content).isEqualTo("this is a string") - } - - @Test - fun `test multi line insert patch`() { - val file = Paths.get("/") - val doc = ActiveDocument(file, 0, Instant.now(), "this is an string") - doc.patch( - DocumentChangeEvent( - file, - "added\nand added\nand added ", - 2, - ChangeType.INSERT, - -1, - Range.pointRange(Position(0, doc.content.length - 6).apply { index = column }) - ) - ) - - assertThat(doc.content).isEqualTo("this is an added\nand added\nand added string") - } - - @Test - fun `test multi line delete patch`() { - val file = Paths.get("/") - val content = "this is an added\nand added\nand added string" - val doc = ActiveDocument(file, 0, Instant.now(), content) - doc.patch( - DocumentChangeEvent( - file, - " added", - 2, - ChangeType.DELETE, - -1, - Range( - Position(0, 9).apply { index = column }, - Position(0, content.length - 7).apply { index = column } - ) - ) - ) - - assertThat(doc.content).isEqualTo("this is a string") - } -}