diff --git a/.androidide_root b/.androidide_root new file mode 100644 index 000000000..42c8f86a2 --- /dev/null +++ b/.androidide_root @@ -0,0 +1,3 @@ +DO NOT DELETE! + +This file is used in tests to check for the project's root directory. 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 f0ce98d4e..b56006afb 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/lsp/testing/build.gradle.kts b/lsp/testing/build.gradle.kts index d8836f0f2..af20a9ed0 100644 --- a/lsp/testing/build.gradle.kts +++ b/lsp/testing/build.gradle.kts @@ -33,10 +33,11 @@ dependencies { implementation(projects.common) implementation(projects.eventbusAndroid) implementation(projects.subprojects.toolingApiTesting) + implementation(projects.shared) + implementation(libs.common.editor) 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 878a33cf4..9a201bb91 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 @@ -39,19 +39,20 @@ import com.itsaky.androidide.tooling.api.messages.InitializeProjectMessage import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher.MultiVersionTestClient import com.itsaky.androidide.utils.Environment +import com.itsaky.androidide.utils.FileProvider import com.itsaky.androidide.utils.ILogger import io.github.rosemoe.sora.text.Content import io.mockk.every import io.mockk.mockkStatic -import java.io.File -import java.nio.file.Path -import kotlin.io.path.pathString import org.greenrobot.eventbus.EventBus import org.junit.Before import org.junit.runner.RunWith 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. @@ -87,7 +88,6 @@ abstract class LSPTest { val (server, project) = ToolingApiTestLauncher() .launchServer( - implDir = FileProvider.implModule().pathString, client = MultiVersionTestClient() ) this.toolingProject = project @@ -96,7 +96,7 @@ abstract class LSPTest { Lookup.DEFAULT.update(BuildService.KEY_PROJECT_PROXY, project) server - .initialize(InitializeProjectMessage(FileProvider.projectRoot().toFile().absolutePath)) + .initialize(InitializeProjectMessage(FileProvider.testProjectRoot().toFile().absolutePath)) .get() Environment.ANDROID_JAR = FileProvider.resources().resolve("android.jar").toFile() @@ -130,7 +130,17 @@ abstract class LSPTest { // As the content has been changed, we have to // Update the content in language server - dispatchEvent(DocumentChangeEvent(file!!, contents.toString(), contents.toString(), 1, DELETE, 0, Range.NONE)) + dispatchEvent( + DocumentChangeEvent( + file!!, + contents.toString(), + contents.toString(), + 1, + DELETE, + 0, + Range.NONE + ) + ) } @JvmOverloads diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 9d75943a6..e0f6284ba 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -25,4 +25,7 @@ dependencies { implementation(libs.androidx.annotation) implementation(libs.google.guava) implementation(projects.logger) + + testImplementation(libs.tests.google.truth) + testImplementation(libs.tests.junit) } \ No newline at end of file diff --git a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/FileProvider.kt b/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt similarity index 61% rename from lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/FileProvider.kt rename to shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt index 096710aa1..9ea7b933b 100644 --- a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/FileProvider.kt +++ b/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt @@ -14,15 +14,21 @@ * You should have received a copy of the GNU General Public License * along with AndroidIDE. If not, see . */ -package com.itsaky.androidide.lsp.api +package com.itsaky.androidide.utils import java.io.File import java.nio.file.Path import java.nio.file.Paths +import kotlin.io.path.ExperimentalPathApi +import kotlin.io.path.absolute +import kotlin.io.path.name import kotlin.io.path.readText +import kotlin.io.path.walk + +const val PROJECT_ROOT_FILE = ".androidide_root" /** - * Provides paths to source files in 'resources' directory. + * Provides paths to various directories and files. * * @author Akash Yadav */ @@ -30,6 +36,10 @@ class FileProvider { companion object { + private val projectRoot by lazy { + currentDir().findProjectRoot()?.absolute()?.normalize() + } + @JvmField val extension = run { val file = File(".").canonicalFile @@ -41,8 +51,15 @@ class FileProvider { @JvmStatic fun currentDir(): Path = Paths.get(System.getProperty("user.dir")!!) - @JvmStatic fun implModule(): Path = currentDir().resolve("../../subprojects/tooling-api-impl") - @JvmStatic fun projectRoot(): Path = currentDir().resolve("../../tests/test-project") + @JvmStatic fun implModule(): Path = projectRoot().resolve("subprojects/tooling-api-impl") + + @JvmStatic + fun projectRoot(): Path = + checkNotNull(projectRoot) { + "Unable to file project root. Check if '${PROJECT_ROOT_FILE}' file exists in the project root directory." + } + + @JvmStatic fun testProjectRoot(): Path = projectRoot().resolve("tests/test-project") /** * Get the path to the 'resources' directory. @@ -51,7 +68,7 @@ class FileProvider { */ @JvmStatic fun resources(): Path { - return projectRoot().resolve("app/src/main/resources") + return testProjectRoot().resolve("app/src/main/resources") } /** @@ -68,3 +85,12 @@ class FileProvider { @JvmStatic fun contents(file: Path): StringBuilder = StringBuilder(file.readText()) } } + +@OptIn(ExperimentalPathApi::class) +private fun Path.findProjectRoot(): Path? { + if (walk().find { it.name == PROJECT_ROOT_FILE } != null) { + return this + } + + return parent?.findProjectRoot() +} diff --git a/lsp/testing/src/test/java/com/itsaky/androidide/lsp/api/FileProviderTest.kt b/shared/src/test/java/com/itsaky/androidide/utils/FileProviderTest.kt similarity index 63% rename from lsp/testing/src/test/java/com/itsaky/androidide/lsp/api/FileProviderTest.kt rename to shared/src/test/java/com/itsaky/androidide/utils/FileProviderTest.kt index 8cff8a61a..650ced6d8 100644 --- a/lsp/testing/src/test/java/com/itsaky/androidide/lsp/api/FileProviderTest.kt +++ b/shared/src/test/java/com/itsaky/androidide/utils/FileProviderTest.kt @@ -15,41 +15,35 @@ * along with AndroidIDE. If not, see . */ -package com.itsaky.androidide.lsp.api +package com.itsaky.androidide.utils -import com.google.common.truth.Truth +import com.google.common.truth.Truth.assertThat +import org.junit.Test import java.io.File import java.nio.file.Files -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -/** @author Akash Yadav */ -@RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE) class FileProviderTest { @Test fun testPath() { val path = FileProvider.sourceFile("SourceFileTest") - Truth.assertThat(Files.exists(path)).isTrue() - Truth.assertThat(path.fileName.toString()).isEqualTo("SourceFileTest_template.java") + assertThat(Files.exists(path)).isTrue() + assertThat(path.fileName.toString()).isEqualTo("SourceFileTest_template.java") } @Test fun testNested() { val path = FileProvider.sourceFile("package/SourceFileTest") - Truth.assertThat(Files.exists(path)).isTrue() - Truth.assertThat(path.fileName.toString()).isEqualTo("SourceFileTest_template.java") + assertThat(Files.exists(path)).isTrue() + assertThat(path.fileName.toString()).isEqualTo("SourceFileTest_template.java") } @Test fun testExtension() { val folder = File(".").canonicalFile - Truth.assertThat(FileProvider.extension).isNotEmpty() - Truth.assertThat(FileProvider.extension) + assertThat(FileProvider.extension).isNotEmpty() + assertThat(FileProvider.extension) .isEqualTo( when (folder.name) { "xml" -> "xml" @@ -57,4 +51,4 @@ class FileProviderTest { } ) } -} +} \ No newline at end of file diff --git a/subprojects/aaptcompiler/build.gradle.kts b/subprojects/aaptcompiler/build.gradle.kts index cf9a09eef..05ea8b9aa 100644 --- a/subprojects/aaptcompiler/build.gradle.kts +++ b/subprojects/aaptcompiler/build.gradle.kts @@ -44,4 +44,5 @@ dependencies { testImplementation(libs.tests.junit) testImplementation(libs.tests.robolectric) testImplementation(libs.tests.google.truth) + testImplementation(projects.shared) } \ No newline at end of file diff --git a/subprojects/aaptcompiler/src/test/java/com/itsaky/androidide/aaptcompiler/CompilerTest.kt b/subprojects/aaptcompiler/src/test/java/com/itsaky/androidide/aaptcompiler/CompilerTest.kt index e73862538..b6346a1f5 100644 --- a/subprojects/aaptcompiler/src/test/java/com/itsaky/androidide/aaptcompiler/CompilerTest.kt +++ b/subprojects/aaptcompiler/src/test/java/com/itsaky/androidide/aaptcompiler/CompilerTest.kt @@ -26,6 +26,7 @@ import com.android.aaptcompiler.compileResource import com.android.aaptcompiler.extractPathData import com.android.utils.StdLogger import com.android.utils.StdLogger.Level.VERBOSE +import com.itsaky.androidide.utils.FileProvider import java.nio.file.Paths import kotlin.io.path.absolute import org.junit.Test @@ -39,7 +40,7 @@ class CompilerTest { @Test fun `test simple compilatation`() { val input = - Paths.get("../../app/src/main/res/layout/activity_editor.xml").absolute().normalize().toFile() + FileProvider.projectRoot().resolve("app/src/main/res/layout/activity_editor.xml").toFile() val output = Paths.get("./build").absolute().normalize().toFile() println(input) println(output) diff --git a/subprojects/projects/build.gradle.kts b/subprojects/projects/build.gradle.kts index cfbdd379a..2ef84b630 100644 --- a/subprojects/projects/build.gradle.kts +++ b/subprojects/projects/build.gradle.kts @@ -34,6 +34,7 @@ dependencies { implementation(libs.google.guava) testImplementation(projects.subprojects.toolingApiTesting) + testImplementation(projects.shared) testImplementation(libs.tests.junit) testImplementation(libs.tests.google.truth) testImplementation(libs.tests.robolectric) diff --git a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/api/ModuleProjectTest.kt b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/api/ModuleProjectTest.kt index d583bfeed..b439b9cf6 100644 --- a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/api/ModuleProjectTest.kt +++ b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/api/ModuleProjectTest.kt @@ -26,15 +26,16 @@ import com.itsaky.androidide.projects.ProjectManager import com.itsaky.androidide.projects.builder.BuildService import com.itsaky.androidide.tooling.api.messages.InitializeProjectMessage import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher +import com.itsaky.androidide.utils.FileProvider import com.itsaky.androidide.utils.SourceClassTrie.SourceNode +import java.io.File +import java.nio.file.Files +import kotlin.io.path.pathString +import kotlin.io.path.writeText import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config -import java.io.File -import java.nio.file.Files -import java.nio.file.Paths -import kotlin.io.path.writeText /** @author Akash Yadav */ @RunWith(RobolectricTestRunner::class) @@ -44,7 +45,7 @@ class ModuleProjectTest { @Test fun test() { val (server, project) = ToolingApiTestLauncher().launchServer() - server.initialize(InitializeProjectMessage(File("../../tests/test-project").absolutePath)).get() + server.initialize(InitializeProjectMessage(FileProvider.testProjectRoot().pathString)).get() Lookup.DEFAULT.register(BuildService.KEY_PROJECT_PROXY, project) @@ -56,8 +57,7 @@ class ModuleProjectTest { val rootDir = root.projectDir assertThat(rootDir).isNotNull() - assertThat(Files.isSameFile(rootDir.toPath(), File("../../tests/test-project").toPath())) - .isTrue() + assertThat(Files.isSameFile(rootDir.toPath(), FileProvider.testProjectRoot())).isTrue() val app = root.findByPath(":app") assertThat(app).isNotNull() @@ -183,7 +183,8 @@ class ModuleProjectTest { private fun verifyProjectManagerAPIs() { val testCls = - Paths.get("../../tests/test-project/app/src/main/java/com/itsaky/test/app/Test.java") + FileProvider.testProjectRoot() + .resolve("app/src/main/java/com/itsaky/test/app/Test.java") .toAbsolutePath() .normalize() val testCls_renamed = testCls.parent!!.resolve("TestRenamed.java") diff --git a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/classpath/ZipFileClasspathReaderTest.kt b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/classpath/ZipFileClasspathReaderTest.kt index 62d4ada9e..cc43238cf 100644 --- a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/classpath/ZipFileClasspathReaderTest.kt +++ b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/classpath/ZipFileClasspathReaderTest.kt @@ -18,7 +18,7 @@ package com.itsaky.androidide.projects.classpath import com.google.common.truth.Truth.assertThat -import java.io.File +import com.itsaky.androidide.utils.FileProvider import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -32,9 +32,12 @@ class ZipFileClasspathReaderTest { @Test fun testListClasses() { val classes = - ZipFileClasspathReader().listClasses( - listOf(File("../../tests/test-project/app/src/main/resources/android.jar")) - ) + ZipFileClasspathReader() + .listClasses( + listOf( + FileProvider.testProjectRoot().resolve("app/src/main/resources/android.jar").toFile() + ) + ) val context = classes.firstOrNull { it.name == "android.content.Context" } assertThat(context).isNotNull() diff --git a/subprojects/tooling-api-impl/build.gradle.kts b/subprojects/tooling-api-impl/build.gradle.kts index ccee2dffa..c73d19763 100644 --- a/subprojects/tooling-api-impl/build.gradle.kts +++ b/subprojects/tooling-api-impl/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { implementation(libs.tooling.gradleApi) testImplementation(projects.subprojects.toolingApiTesting) + testImplementation(projects.shared) testImplementation(libs.tests.junit) testImplementation(libs.tests.google.truth) diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt index bcb8c6121..d030f0d53 100644 --- a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt +++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/MultiModuleAndroidProjectTest.kt @@ -30,11 +30,12 @@ import com.itsaky.androidide.tooling.api.model.JavaModuleExternalDependency import com.itsaky.androidide.tooling.api.model.JavaModuleProjectDependency import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher.MultiVersionTestClient +import com.itsaky.androidide.utils.FileProvider +import kotlin.io.path.deleteExisting +import kotlin.io.path.pathString import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 -import java.io.File -import kotlin.jvm.Throws /** @author Akash Yadav */ @RunWith(JUnit4::class) @@ -42,8 +43,8 @@ class MultiModuleAndroidProjectTest { @Test fun `test simple multi module project initialization`() { - val (server, project) = ToolingApiTestLauncher().launchServer(client = MultiVersionTestClient("7.2.0")) - server.initialize(InitializeProjectMessage(File("../../tests/test-project").absolutePath)).get() + val (server, project) = ToolingApiTestLauncher().launchServer() + server.initialize(InitializeProjectMessage(FileProvider.testProjectRoot().pathString)).get() doAssertions(project, server) } @@ -148,37 +149,35 @@ class MultiModuleAndroidProjectTest { val versions = listOf("7.2.0", "7.2.1", "7.2.2", "7.3.0", "7.4.0", "8.0.0-rc01") val client = MultiVersionTestClient() for (version in versions) { - client.version = version + client.agpVersion = version val (server, project) = ToolingApiTestLauncher().launchServer(client = client) - server - .initialize(InitializeProjectMessage(File("../../tests/test-project").absolutePath)) - .get() + server.initialize(InitializeProjectMessage(FileProvider.testProjectRoot().pathString)).get() doAssertions(project = project, server = server) - MultiVersionTestClient.buildFile.delete() + FileProvider.testProjectRoot().resolve(MultiVersionTestClient.buildFile).deleteExisting() } } } - + private fun ciOnlyTest(test: () -> Unit) { try { assertIsCI() test() } catch (err: CIOnlyException) { - if(shouldTestMultipleVersions()) { + if (shouldTestMultipleVersions()) { throw err } } } - + private fun assertIsCI() { if (!shouldTestMultipleVersions()) { throw CIOnlyException() } } - - private fun shouldTestMultipleVersions() : Boolean { + + private fun shouldTestMultipleVersions(): Boolean { return System.getenv("TEST_TOOLING_API_IMPL").let { it == "true" } } - + private class CIOnlyException : IllegalStateException() } diff --git a/subprojects/tooling-api-testing/build.gradle.kts b/subprojects/tooling-api-testing/build.gradle.kts index 1ba00b857..6f3b4e9e9 100644 --- a/subprojects/tooling-api-testing/build.gradle.kts +++ b/subprojects/tooling-api-testing/build.gradle.kts @@ -25,7 +25,8 @@ dependencies { implementation(libs.common.jkotlin) implementation(projects.logger) implementation(projects.subprojects.toolingApi) - + implementation(projects.shared) + // build tooling API before tests compileOnly(projects.subprojects.toolingApiImpl) } \ No newline at end of file diff --git a/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt b/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt index 4c3ea1753..c3317dc83 100644 --- a/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt +++ b/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt @@ -25,13 +25,19 @@ import com.itsaky.androidide.tooling.api.messages.result.BuildResult import com.itsaky.androidide.tooling.api.messages.result.GradleWrapperCheckResult import com.itsaky.androidide.tooling.api.util.ToolingApiLauncher import com.itsaky.androidide.tooling.events.ProgressEvent +import com.itsaky.androidide.utils.FileProvider import com.itsaky.androidide.utils.ILogger import java.io.BufferedReader import java.io.File import java.io.InputStream import java.io.InputStreamReader +import java.nio.file.Path import java.util.Collections import java.util.concurrent.CompletableFuture +import kotlin.io.path.bufferedReader +import kotlin.io.path.bufferedWriter +import kotlin.io.path.deleteIfExists +import kotlin.io.path.pathString /** * Launches the Tooling API server in a separate JVM process. @@ -46,7 +52,7 @@ class ToolingApiTestLauncher { private val opens = mutableMapOf("java.base" to "java.lang", "java.base" to "java.util", "java.base" to "java.io") - + private val exports = mutableMapOf( "jdk.compiler" to "com.sun.tools.javac.api", @@ -57,10 +63,14 @@ class ToolingApiTestLauncher { ) fun launchServer( - client: IToolingApiClient = TestClient(), - implDir: String = "../tooling-api-impl" + client: IToolingApiClient = MultiVersionTestClient(), ): Pair { - val builder = ProcessBuilder(createProcessCmd("$implDir/build/libs/tooling-api-all.jar")) + val builder = + ProcessBuilder( + createProcessCmd( + FileProvider.implModule().resolve("build/libs/tooling-api-all.jar").pathString + ) + ) val androidHome = findAndroidHome() println("ANDROID_HOME=$androidHome") builder.environment()["ANDROID_SDK_ROOT"] = androidHome @@ -86,9 +96,9 @@ class ToolingApiTestLauncher { } Collections.addAll(cmd, "-jar", jar) - + println("[ToolingApiTestLauncher] Java cmd: " + cmd.joinToString(separator = " ")) - + return cmd } @@ -112,8 +122,26 @@ class ToolingApiTestLauncher { } } - open class TestClient : IToolingApiClient { - private val log = ILogger.newInstance(javaClass.simpleName) + class MultiVersionTestClient( + private val projectDir: Path = FileProvider.testProjectRoot(), + var agpVersion: String = DEFAULT_AGP_VERSION, + var gradleVersion: String = DEFAULT_GRADLE_VERSION + ) : IToolingApiClient { + + companion object { + const val buildFile = "build.gradle" + const val buildFileIn = "$buildFile.in" + + const val gradlewProps = "gradle/wrapper/gradle-wrapper.properties" + const val gradlewPropsIn = "$gradlewProps.in" + + const val DEFAULT_AGP_VERSION = "7.2.0" + const val DEFAULT_GRADLE_VERSION = "7.5.1" + + const val GENERATED_FILE_WARNING = "DO NOT EDIT - Automatically generated file" + + private val log = ILogger.newInstance("MultiVersionTestClient") + } override fun logMessage(line: LogLine) { log.log(line.priority, line.formattedTagAndMessage()) } @@ -122,7 +150,27 @@ class ToolingApiTestLauncher { log.debug(line.trim()) } - override fun prepareBuild() {} + override fun prepareBuild() { + log.debug("-----------------------------------") + log.debug("---------- PREPARE BUILD ----------") + log.debug("-----------------------------------") + + projectDir + .resolve(buildFileIn) + .replaceContents( + dest = projectDir.resolve(buildFile), + candidate = "@@TOOLING_API_TEST_AGP_VERSION@@" to this.agpVersion + ) + + projectDir + .resolve(gradlewPropsIn) + .replaceContents( + comment = "#", + dest = projectDir.resolve(gradlewProps), + candidate = "@@GRADLE_VERSION@@" to this.gradleVersion + ) + } + override fun onBuildSuccessful(result: BuildResult) {} override fun onBuildFailed(result: BuildResult) {} @@ -134,24 +182,40 @@ class ToolingApiTestLauncher { override fun checkGradleWrapperAvailability(): CompletableFuture = CompletableFuture.completedFuture(GradleWrapperCheckResult(true)) - } - class MultiVersionTestClient(var version: String = "7.2.0") : TestClient() { + private fun Path.replaceContents( + dest: Path, + comment: String = "//", + candidate: Pair + ) = replaceContents(dest, comment, *arrayOf(candidate)) - companion object { - val buildTemplateFile = File("../../tests/test-project/build.gradle.in") - val buildFile = File(buildTemplateFile.parentFile, "build.gradle") - } + private fun Path.replaceContents( + dest: Path, + comment: String = "//", + vararg candidates: Pair + ) { + val contents = + StringBuilder() + .append(comment) + .append(" ") + .append(GENERATED_FILE_WARNING) + .append(System.getProperty("line.separator").repeat(2)) - override fun prepareBuild() { - super.prepareBuild() - var contents = buildTemplateFile.bufferedReader().readText() - contents = contents.replace("@@TOOLING_API_TEST_AGP_VERSION@@", this.version) - contents = "/* DO NOT EDIT - Automatically generated file */\n${contents.trim()}" - val writer = buildFile.bufferedWriter() - writer.use { - it.write(contents) - it.flush() + bufferedReader().use { reader -> + reader.readText().also { text -> + var t = text + for ((old, new) in candidates) { + t = t.replace(old, new) + } + contents.append(t) + } + } + + dest.deleteIfExists() + + dest.bufferedWriter().use { writer -> + writer.write(contents.toString()) + writer.flush() } } } diff --git a/tests/test-project/.gitignore b/tests/test-project/.gitignore index d16386367..e79b450ef 100644 --- a/tests/test-project/.gitignore +++ b/tests/test-project/.gitignore @@ -1 +1,2 @@ -build/ \ No newline at end of file +/build.gradle +build/ diff --git a/tests/test-project/build.gradle b/tests/test-project/build.gradle index fc73698b5..6204bf799 100644 --- a/tests/test-project/build.gradle +++ b/tests/test-project/build.gradle @@ -1,4 +1,5 @@ -/* DO NOT EDIT - Automatically generated file */ +// DO NOT EDIT - Automatically generated file + buildscript { ext { build_gradle_version = "7.2.0" @@ -34,4 +35,4 @@ allprojects { task clean (type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +} diff --git a/tests/test-project/gradle/wrapper/.gitignore b/tests/test-project/gradle/wrapper/.gitignore new file mode 100644 index 000000000..5c09825f6 --- /dev/null +++ b/tests/test-project/gradle/wrapper/.gitignore @@ -0,0 +1 @@ +gradle-wrapper.properties diff --git a/tests/test-project/gradle/wrapper/gradle-wrapper.properties b/tests/test-project/gradle/wrapper/gradle-wrapper.properties.in similarity index 84% rename from tests/test-project/gradle/wrapper/gradle-wrapper.properties rename to tests/test-project/gradle/wrapper/gradle-wrapper.properties.in index 0bd1f1838..621ebcd18 100644 --- a/tests/test-project/gradle/wrapper/gradle-wrapper.properties +++ b/tests/test-project/gradle/wrapper/gradle-wrapper.properties.in @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-@@GRADLE_VERSION@@-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/xml-inflater/build.gradle.kts b/xml-inflater/build.gradle.kts index 936c12af1..3e203ebb5 100644 --- a/xml-inflater/build.gradle.kts +++ b/xml-inflater/build.gradle.kts @@ -42,6 +42,7 @@ dependencies { testImplementation(projects.subprojects.projects) testImplementation(projects.subprojects.toolingApiTesting) + testImplementation(projects.shared) testImplementation(libs.tests.junit) testImplementation(libs.tests.google.truth) testImplementation(libs.tests.robolectric) diff --git a/xml-inflater/src/test/java/com/itsaky/androidide/inflater/XmlInflaterTest.kt b/xml-inflater/src/test/java/com/itsaky/androidide/inflater/XmlInflaterTest.kt index 4650a62d6..ebeb1c1ad 100644 --- a/xml-inflater/src/test/java/com/itsaky/androidide/inflater/XmlInflaterTest.kt +++ b/xml-inflater/src/test/java/com/itsaky/androidide/inflater/XmlInflaterTest.kt @@ -26,9 +26,11 @@ import com.itsaky.androidide.projects.api.AndroidModule import com.itsaky.androidide.projects.builder.BuildService import com.itsaky.androidide.tooling.api.messages.InitializeProjectMessage import com.itsaky.androidide.tooling.testing.ToolingApiTestLauncher +import com.itsaky.androidide.utils.FileProvider import java.io.File import org.junit.Ignore import org.robolectric.Robolectric +import kotlin.io.path.pathString @Ignore("Test utility provider") object XmlInflaterTest { @@ -42,8 +44,8 @@ object XmlInflaterTest { } val (server, project) = - ToolingApiTestLauncher().launchServer(implDir = "../subprojects/tooling-api-impl") - server.initialize(InitializeProjectMessage(File("../tests/test-project").absolutePath)).get() + ToolingApiTestLauncher().launchServer() + server.initialize(InitializeProjectMessage(FileProvider.testProjectRoot().pathString)).get() Lookup.DEFAULT.register(BuildService.KEY_PROJECT_PROXY, project) ProjectManager.setupProject()