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 c7f779674..e6c0898d5 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 @@ -44,148 +44,150 @@ class ModuleProjectTest { @Test fun test() { - val (_, project, result) = ToolingApiTestLauncher().launchServer() - assertThat(result?.isSuccessful).isTrue() + ToolingApiTestLauncher.launchServer() { - Lookup.getDefault().register(BuildService.KEY_PROJECT_PROXY, project) + assertThat(result?.isSuccessful).isTrue() - verifyProjectManagerAPIs() + Lookup.getDefault().register(BuildService.KEY_PROJECT_PROXY, project) - assertThat(project).isNotNull() + verifyProjectManagerAPIs() - val rootProject = IProjectManager.getInstance().rootProject - assertThat(rootProject).isNotNull() + assertThat(project).isNotNull() - val root = rootProject!!.rootProject - assertThat(root).isNotNull() - assertThat(root.name).isEqualTo("TestApp") + val rootProject = IProjectManager.getInstance().rootProject + assertThat(rootProject).isNotNull() - val rootDir = root.projectDir - assertThat(rootDir).isNotNull() - assertThat(Files.isSameFile(rootDir.toPath(), FileProvider.testProjectRoot())).isTrue() + val root = rootProject!!.rootProject + assertThat(root).isNotNull() + assertThat(root.name).isEqualTo("TestApp") - val app = rootProject.findByPath(":app") - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(AndroidModule::class.java) + val rootDir = root.projectDir + assertThat(rootDir).isNotNull() + assertThat(Files.isSameFile(rootDir.toPath(), FileProvider.testProjectRoot())).isTrue() - val appSourceDirs = (app as AndroidModule).getSourceDirectories() - assertThat(appSourceDirs).isNotEmpty() - assertThat(appSourceDirs) - .containsAtLeast(File(rootDir, "app/src/main/java"), File(rootDir, "app/src/main/kotlin")) - assertThat(appSourceDirs).doesNotContain(File(rootDir, "other-java-library/src/main/java")) - assertThat(app.compilerSettings.javaSourceVersion).isEqualTo("11") - assertThat(app.compilerSettings.javaBytecodeVersion).isEqualTo("11") - assertThat(app.compilerSettings.javaSourceVersion) - .isEqualTo(app.compilerSettings.sourceCompatibility) - assertThat(app.compilerSettings.javaBytecodeVersion) - .isEqualTo(app.compilerSettings.targetCompatibility) + val app = rootProject.findByPath(":app") + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(AndroidModule::class.java) - val anotherAndroidLib = rootProject.findByPath(":another-android-library") - assertThat(anotherAndroidLib).isNotNull() - assertThat(anotherAndroidLib).isInstanceOf(AndroidModule::class.java) + val appSourceDirs = (app as AndroidModule).getSourceDirectories() + assertThat(appSourceDirs).isNotEmpty() + assertThat(appSourceDirs) + .containsAtLeast(File(rootDir, "app/src/main/java"), File(rootDir, "app/src/main/kotlin")) + assertThat(appSourceDirs).doesNotContain(File(rootDir, "other-java-library/src/main/java")) + assertThat(app.compilerSettings.javaSourceVersion).isEqualTo("11") + assertThat(app.compilerSettings.javaBytecodeVersion).isEqualTo("11") + assertThat(app.compilerSettings.javaSourceVersion) + .isEqualTo(app.compilerSettings.sourceCompatibility) + assertThat(app.compilerSettings.javaBytecodeVersion) + .isEqualTo(app.compilerSettings.targetCompatibility) - val anotherAndroidLibDir = anotherAndroidLib!!.projectDir + val anotherAndroidLib = rootProject.findByPath(":another-android-library") + assertThat(anotherAndroidLib).isNotNull() + assertThat(anotherAndroidLib).isInstanceOf(AndroidModule::class.java) - val androidLibSourceDirs = (anotherAndroidLib as AndroidModule).getSourceDirectories() - assertThat(androidLibSourceDirs).isNotEmpty() - assertThat(androidLibSourceDirs) - .contains(File(rootDir, "another-android-library/src/main/java")) + val anotherAndroidLibDir = anotherAndroidLib!!.projectDir - assertThat(anotherAndroidLib.getCompileClasspaths()) - .containsAtLeast( - File( - anotherAndroidLibDir, - "build/${IAndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar" - ), - File( - anotherAndroidLibDir, - "build/${IAndroidProject.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar" - ) - ) - assertThat( - anotherAndroidLib.getCompileClasspaths().firstOrNull { - it.name == "nb-javac-android-17.0.0.0.jar" - } - ) - .isNotNull() + val androidLibSourceDirs = (anotherAndroidLib as AndroidModule).getSourceDirectories() + assertThat(androidLibSourceDirs).isNotEmpty() + assertThat(androidLibSourceDirs) + .contains(File(rootDir, "another-android-library/src/main/java")) - assertThat(anotherAndroidLib.getCompileSourceDirectories()) - .containsAtLeast( - File(anotherAndroidLibDir, "src/main/java"), - File(anotherAndroidLibDir, "src/main/kotlin"), - File(rootDir, "other-java-library/src/main/java") - ) - - assertThat(anotherAndroidLib.compilerSettings.javaSourceVersion).isEqualTo("11") - assertThat(anotherAndroidLib.compilerSettings.javaBytecodeVersion).isEqualTo("11") - - val appCompileSourceDirs = app.getCompileSourceDirectories() - assertThat(appCompileSourceDirs).isNotEmpty() - assertThat(appCompileSourceDirs) - .containsAtLeast( - File(rootDir, "app/src/main/java"), - File(rootDir, "app/src/main/kotlin"), - File(anotherAndroidLibDir, "src/main/java") - ) - - app.getCompileClasspaths().apply { - assertThat(this).isNotEmpty() - assertThat(this) + assertThat(anotherAndroidLib.getCompileClasspaths()) .containsAtLeast( File( anotherAndroidLibDir, "build/${IAndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar" ), - File( - app.projectDir, - "build/${IAndroidProject.FD_INTERMEDIATES}/compile_and_runtime_not_namespaced_r_class_jar/debug/R.jar" - ), File( anotherAndroidLibDir, "build/${IAndroidProject.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar" ) ) assertThat( - filter { - it.absolutePath.endsWith("appcompat-1.5.1/jars/classes.jar") || - it.absolutePath.endsWith("material-1.8.0-alpha01/jars/classes.jar") || - it.absolutePath.endsWith("coordinatorlayout-1.2.0/jars/classes.jar") + anotherAndroidLib.getCompileClasspaths().firstOrNull { + it.name == "nb-javac-android-17.0.0.0.jar" } ) - .hasSize(3) - } + .isNotNull() - val javaLibrary = rootProject.findByPath(":java-library") - assertThat(javaLibrary).isNotNull() - assertThat(javaLibrary).isInstanceOf(JavaModule::class.java) + assertThat(anotherAndroidLib.getCompileSourceDirectories()) + .containsAtLeast( + File(anotherAndroidLibDir, "src/main/java"), + File(anotherAndroidLibDir, "src/main/kotlin"), + File(rootDir, "other-java-library/src/main/java") + ) - val javaLibSourceDirs = (javaLibrary as JavaModule).getSourceDirectories() - assertThat(javaLibSourceDirs).isNotEmpty() - assertThat(javaLibSourceDirs).contains(File(rootDir, "java-library/src/main/java")) + assertThat(anotherAndroidLib.compilerSettings.javaSourceVersion).isEqualTo("11") + assertThat(anotherAndroidLib.compilerSettings.javaBytecodeVersion).isEqualTo("11") - app.indexSourcesAndClasspaths() + val appCompileSourceDirs = app.getCompileSourceDirectories() + assertThat(appCompileSourceDirs).isNotEmpty() + assertThat(appCompileSourceDirs) + .containsAtLeast( + File(rootDir, "app/src/main/java"), + File(rootDir, "app/src/main/kotlin"), + File(anotherAndroidLibDir, "src/main/java") + ) - val classes = app.compileJavaSourceClasses.findInPackage("com.itsaky") - assertThat(classes).isNotNull() - assertThat(classes).isNotEmpty() - - for (klass in arrayOf( - "com.itsaky.androidide.tooling.test.Main", - "com.itsaky.test.app.MainActivity") - ) { - - classes.find { it.qualifiedName == klass }.let { - assertThat(it).isNotNull() - assertThat(it!!.isClass).isTrue() - assertThat(it::class.java) + app.getCompileClasspaths().apply { + assertThat(this).isNotEmpty() + assertThat(this) + .containsAtLeast( + File( + anotherAndroidLibDir, + "build/${IAndroidProject.FD_INTERMEDIATES}/compile_library_classes_jar/debug/classes.jar" + ), + File( + app.projectDir, + "build/${IAndroidProject.FD_INTERMEDIATES}/compile_and_runtime_not_namespaced_r_class_jar/debug/R.jar" + ), + File( + anotherAndroidLibDir, + "build/${IAndroidProject.FD_INTERMEDIATES}/compile_r_class_jar/debug/R.jar" + ) + ) + assertThat( + filter { + it.absolutePath.endsWith("appcompat-1.5.1/jars/classes.jar") || + it.absolutePath.endsWith("material-1.8.0-alpha01/jars/classes.jar") || + it.absolutePath.endsWith("coordinatorlayout-1.2.0/jars/classes.jar") + } + ) + .hasSize(3) } - } - rootProject.findByPath(":another-java-library").run { - assertThat(this).isInstanceOf(JavaModule::class.java) - assertThat((this as JavaModule).compilerSettings).isNotNull() - assertThat(compilerSettings.javaSourceVersion).isEqualTo("1.8") - assertThat(compilerSettings.javaBytecodeVersion).isEqualTo("1.8") + val javaLibrary = rootProject.findByPath(":java-library") + assertThat(javaLibrary).isNotNull() + assertThat(javaLibrary).isInstanceOf(JavaModule::class.java) + + val javaLibSourceDirs = (javaLibrary as JavaModule).getSourceDirectories() + assertThat(javaLibSourceDirs).isNotEmpty() + assertThat(javaLibSourceDirs).contains(File(rootDir, "java-library/src/main/java")) + + app.indexSourcesAndClasspaths() + + val classes = app.compileJavaSourceClasses.findInPackage("com.itsaky") + assertThat(classes).isNotNull() + assertThat(classes).isNotEmpty() + + for (klass in arrayOf( + "com.itsaky.androidide.tooling.test.Main", + "com.itsaky.test.app.MainActivity") + ) { + + classes.find { it.qualifiedName == klass }.let { + assertThat(it).isNotNull() + assertThat(it!!.isClass).isTrue() + assertThat(it::class.java) + } + } + + rootProject.findByPath(":another-java-library").run { + assertThat(this).isInstanceOf(JavaModule::class.java) + assertThat((this as JavaModule).compilerSettings).isNotNull() + assertThat(compilerSettings.javaSourceVersion).isEqualTo("1.8") + assertThat(compilerSettings.javaBytecodeVersion).isEqualTo("1.8") + } } } diff --git a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/util/ClassTrieTest.kt b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/util/ClassTrieTest.kt index 41a8c3c86..9700789df 100644 --- a/subprojects/projects/src/test/java/com/itsaky/androidide/projects/util/ClassTrieTest.kt +++ b/subprojects/projects/src/test/java/com/itsaky/androidide/projects/util/ClassTrieTest.kt @@ -31,7 +31,7 @@ class ClassTrieTest { @Test fun testAppend() { - val trie = com.itsaky.androidide.utils.ClassTrie() + val trie = ClassTrie() trie.append("java.lang.String") trie.append("java.lang.String.Inner") trie.append("java.lang.Object") @@ -48,7 +48,7 @@ class ClassTrieTest { @Test fun testRemoval() { - val trie = com.itsaky.androidide.utils.ClassTrie() + val trie = ClassTrie() trie.append("java.lang.String") trie.append("java.lang.Object") trie.append("java.util.List") diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ApplicationIDComputationTest.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ApplicationIDComputationTest.kt index f658ba4e2..5a2235cdc 100644 --- a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ApplicationIDComputationTest.kt +++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ApplicationIDComputationTest.kt @@ -34,35 +34,36 @@ class ApplicationIDComputationTest { @Test fun `test variant-specific application ID computation for default applicationId`() { // no custom applicationIdSuffix or applicationId is set - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer() + ToolingApiTestLauncher.launchServer { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(2) - assertThat(variants.map { it.name }).containsExactly("debug", "release") + assertThat(variants).hasSize(2) + assertThat(variants.map { it.name }).containsExactly("debug", "release") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() - assertThat(applicationId).isEqualTo("com.itsaky.test.app") + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() + assertThat(applicationId).isEqualTo("com.itsaky.test.app") + } } } @@ -86,36 +87,37 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(4) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", + assertThat(variants).hasSize(4) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", "demoRelease") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() - assertThat(applicationId).isAnyOf("com.itsaky.test.app.full", "com.itsaky.test.app.demo") + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() + assertThat(applicationId).isAnyOf("com.itsaky.test.app.full", "com.itsaky.test.app.demo") + } } } @@ -144,39 +146,41 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(8) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "fullStaging", + assertThat(variants).hasSize(8) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", + "fullStaging", "fullExperimental", "demoDebug", "demoRelease", "demoStaging", "demoExperimental") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() - // the build types don't have any applicationIdSuffix set - // so only suffix from the flavors should be applied here - assertThat(applicationId).isAnyOf("com.itsaky.test.app.full", "com.itsaky.test.app.demo") + // the build types don't have any applicationIdSuffix set + // so only suffix from the flavors should be applied here + assertThat(applicationId).isAnyOf("com.itsaky.test.app.full", "com.itsaky.test.app.demo") + } } } @@ -196,37 +200,38 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(4) - assertThat(variants.map { it.name }).containsExactly("debug", "release", "staging", - "experimental") + assertThat(variants).hasSize(4) + assertThat(variants.map { it.name }).containsExactly("debug", "release", "staging", + "experimental") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() - assertThat(applicationId).isAnyOf("com.itsaky.test.app", "com.itsaky.test.app.staging", - "com.itsaky.test.app.experimental") + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() + assertThat(applicationId).isAnyOf("com.itsaky.test.app", "com.itsaky.test.app.staging", + "com.itsaky.test.app.experimental") + } } } @@ -257,40 +262,42 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(8) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "fullStaging", + assertThat(variants).hasSize(8) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", + "fullStaging", "fullExperimental", "demoDebug", "demoRelease", "demoStaging", "demoExperimental") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() - // the flavors don't have any applicationIdSuffix set - // so only suffix from the build types should be applied here - assertThat(applicationId).isAnyOf("com.itsaky.test.app", "com.itsaky.test.app.staging", - "com.itsaky.test.app.experimental") + // the flavors don't have any applicationIdSuffix set + // so only suffix from the build types should be applied here + assertThat(applicationId).isAnyOf("com.itsaky.test.app", "com.itsaky.test.app.staging", + "com.itsaky.test.app.experimental") + } } } @@ -323,45 +330,47 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(8) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "fullStaging", + assertThat(variants).hasSize(8) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", + "fullStaging", "fullExperimental", "demoDebug", "demoRelease", "demoStaging", "demoExperimental") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() - // the flavors don't have any applicationIdSuffix set - // so only suffix from the build types should be applied here - assertThat(applicationId).isAnyOf( - // 'debug' and 'release' build types - "com.itsaky.test.app.full", "com.itsaky.test.app.demo", + // the flavors don't have any applicationIdSuffix set + // so only suffix from the build types should be applied here + assertThat(applicationId).isAnyOf( + // 'debug' and 'release' build types + "com.itsaky.test.app.full", "com.itsaky.test.app.demo", - // custom build types with applicationIdSuffix - "com.itsaky.test.app.full.staging", "com.itsaky.test.app.demo.staging", - "com.itsaky.test.app.full.experimental", "com.itsaky.test.app.demo.experimental") + // custom build types with applicationIdSuffix + "com.itsaky.test.app.full.staging", "com.itsaky.test.app.demo.staging", + "com.itsaky.test.app.full.experimental", "com.itsaky.test.app.demo.experimental") + } } } @@ -385,36 +394,37 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(4) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", + assertThat(variants).hasSize(4) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", "demoRelease") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() - assertThat(applicationId).isAnyOf("com.androidide.app.full", "com.androidide.app.demo") + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() + assertThat(applicationId).isAnyOf("com.androidide.app.full", "com.androidide.app.demo") + } } } @@ -438,36 +448,37 @@ class ApplicationIDComputationTest { val client = ToolingApiTestLauncher.MultiVersionTestClient( androidBlockConfig = androidBlockConfig) - val (_, project, initializeResult) = ToolingApiTestLauncher().launchServer(client = client) + ToolingApiTestLauncher.launchServer(client = client) { - assertThat(initializeResult).isNotNull() - assertThat(initializeResult?.isSuccessful).isTrue() - assertThat(initializeResult?.failure).isNull() + assertThat(result).isNotNull() + assertThat(result?.isSuccessful).isTrue() + assertThat(result?.failure).isNull() - assertThat(project).isNotNull() + assertThat(project).isNotNull() - val selectionResult = project.selectProject(StringParameter(":app")).get() - assertThat(selectionResult).isNotNull() - assertThat(selectionResult.isSuccessful).isTrue() + val selectionResult = project.selectProject(StringParameter(":app")).get() + assertThat(selectionResult).isNotNull() + assertThat(selectionResult.isSuccessful).isTrue() - val app = project.asAndroidProject() - assertThat(app).isNotNull() - assertThat(app).isInstanceOf(IAndroidProject::class.java) + val app = project.asAndroidProject() + assertThat(app).isNotNull() + assertThat(app).isInstanceOf(IAndroidProject::class.java) - val variants = app.getVariants().get() - assertThat(variants).isNotNull() - assertThat(variants).isNotEmpty() + val variants = app.getVariants().get() + assertThat(variants).isNotNull() + assertThat(variants).isNotEmpty() - assertThat(variants).hasSize(4) - assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", + assertThat(variants).hasSize(4) + assertThat(variants.map { it.name }).containsExactly("fullDebug", "fullRelease", "demoDebug", "demoRelease") - variants.forEach { variant -> - val applicationId = variant.mainArtifact.applicationId - assertThat(applicationId).isNotNull() - assertThat(applicationId?.trim()).isNotEmpty() - assertThat(applicationId).isAnyOf("com.androidide.app.full", "com.itsaky.test.app.demo") + variants.forEach { variant -> + val applicationId = variant.mainArtifact.applicationId + assertThat(applicationId).isNotNull() + assertThat(applicationId?.trim()).isNotEmpty() + assertThat(applicationId).isAnyOf("com.androidide.app.full", "com.itsaky.test.app.demo") + } } } } \ No newline at end of file diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/CIOnlyToolingApiTests.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/CIOnlyToolingApiTests.kt index 1481a44f4..bb19ac56e 100644 --- a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/CIOnlyToolingApiTests.kt +++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/CIOnlyToolingApiTests.kt @@ -46,53 +46,47 @@ class CIOnlyToolingApiTests { @Test fun `test CI-only simple multi module project initialization with multiple AGP versions`() { // Test the minimum supported and the latest AGP version - val versions = - listOf( - // AGP to Gradle - BuildInfo.AGP_VERSION_MININUM to "7.3.3", - BuildInfo.AGP_VERSION_LATEST to "8.2" - ) + val versions = listOf( + // AGP to Gradle + BuildInfo.AGP_VERSION_MININUM to "7.3.3", BuildInfo.AGP_VERSION_LATEST to "8.2") val client = ToolingApiTestLauncher.MultiVersionTestClient() for ((agpVersion, gradleVersion) in versions) { client.agpVersion = agpVersion client.gradleVersion = gradleVersion - val (server, project, result) = ToolingApiTestLauncher().launchServer(client = client) - assertThat(result?.isSuccessful).isTrue() + ToolingApiTestLauncher.launchServer(client = client) { + assertThat(result?.isSuccessful).isTrue() - performBasicProjectAssertions(project = project, server = server) + performBasicProjectAssertions(project = project, server = server) + } } } @Test fun `test CI-only latest tested AGP version warning`() { - val log = CollectingLogger() + val log = CollectingLogger() val agpVersion = AndroidPluginVersion.parse(BuildInfo.AGP_VERSION_LATEST) val client = ToolingApiTestLauncher.MultiVersionTestClient( agpVersion = agpVersion.toStringSimple(), gradleVersion = "${agpVersion.major}.${agpVersion.minor}", log = log) - val (_, project, result) = ToolingApiTestLauncher().launchServer( - client = client, - log = log, - sysProps = mapOf( - ToolingProps.TESTING_LATEST_AGP_VERSION to ToolingApiTestLauncher.MultiVersionTestClient.DEFAULT_AGP_VERSION) - ) - val output = log.toString() + ToolingApiTestLauncher.launchServer(client = client, log = log, sysProps = mapOf( + ToolingProps.TESTING_LATEST_AGP_VERSION to ToolingApiTestLauncher.MultiVersionTestClient.DEFAULT_AGP_VERSION)) { + val output = log.toString() - if (result?.isSuccessful != true) { - // print the output if the initialization fails - println(output) + if (result?.isSuccessful != true) { + // print the output if the initialization fails + println(output) + } + + assertThat(result?.isSuccessful).isTrue() + + val syncIssues = project.getProjectSyncIssues().get() + assertThat(syncIssues).isNotNull() + assertThat(syncIssues.syncIssues).isNotEmpty() + assertThat( + syncIssues.syncIssues.find { it.type == IDESyncIssue.TYPE_AGP_VERSION_TOO_NEW }).isNotNull() } - - assertThat(result?.isSuccessful).isTrue() - - val syncIssues = project.getProjectSyncIssues().get() - assertThat(syncIssues).isNotNull() - assertThat(syncIssues.syncIssues).isNotEmpty() - assertThat( - syncIssues.syncIssues.find { it.type == IDESyncIssue.TYPE_AGP_VERSION_TOO_NEW } - ).isNotNull() } @Test @@ -101,11 +95,12 @@ class CIOnlyToolingApiTests { val agpVersion = "7.1.0" val client = ToolingApiTestLauncher.MultiVersionTestClient(agpVersion = agpVersion, gradleVersion = "7.2", log = log) - val (_, _, result) = ToolingApiTestLauncher().launchServer(client = client, log = log) - assertThat(result?.isSuccessful).isFalse() + ToolingApiTestLauncher.launchServer(client = client, log = log) { + assertThat(result?.isSuccessful).isFalse() - val output = log.toString() - assertThat(output).contains( - "Android Gradle Plugin version $agpVersion is not supported by AndroidIDE.") + val output = log.toString() + assertThat(output).contains( + "Android Gradle Plugin version $agpVersion is not supported by AndroidIDE.") + } } } \ No newline at end of file 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 bb52514f2..b7e384004 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 @@ -44,17 +44,18 @@ class MultiModuleAndroidProjectTest { @Test fun `test simple multi module project initialization`() { - val (server, project, result) = ToolingApiTestLauncher().launchServer() - assertThat(result?.isSuccessful).isTrue() - performBasicProjectAssertions(project, server) + ToolingApiTestLauncher.launchServer { + assertThat(result?.isSuccessful).isTrue() + performBasicProjectAssertions(project, server) + } } @Test fun `test non-existing project initialization`() { - val (_, _, result) = ToolingApiTestLauncher().launchServer( - projectDir = Paths.get("/directory/does/not/exist/")) - assertThat(result?.isSuccessful).isFalse() - assertThat(result?.failure).isEqualTo(TaskExecutionResult.Failure.PROJECT_NOT_FOUND) + ToolingApiTestLauncher.launchServer(projectDir = Paths.get("/directory/does/not/exist/")) { + assertThat(result?.isSuccessful).isFalse() + assertThat(result?.failure).isEqualTo(TaskExecutionResult.Failure.PROJECT_NOT_FOUND) + } } @Test @@ -64,9 +65,10 @@ class MultiModuleAndroidProjectTest { path.deleteIfExists() path.createFile() - val (_, _, result) = ToolingApiTestLauncher().launchServer(projectDir = path) - assertThat(result?.isSuccessful).isFalse() - assertThat(result?.failure).isEqualTo(TaskExecutionResult.Failure.PROJECT_NOT_DIRECTORY) + ToolingApiTestLauncher.launchServer(projectDir = path) { + assertThat(result?.isSuccessful).isFalse() + assertThat(result?.failure).isEqualTo(TaskExecutionResult.Failure.PROJECT_NOT_DIRECTORY) + } } @Test @@ -91,50 +93,32 @@ class MultiModuleAndroidProjectTest { } } - val (server, project, result) = ToolingApiTestLauncher().launchServer(client = client) - assertThat(server).isNotNull() - assertThat(project).isNotNull() - assertThat(result?.isSuccessful).isTrue() + ToolingApiTestLauncher.launchServer(client = client) { + assertThat(server).isNotNull() + assertThat(project).isNotNull() + assertThat(result?.isSuccessful).isTrue() - println("Executed tasks during initialization : " + taskPaths.joinToString( - separator = System.lineSeparator())) - taskPaths.clear() + println("Executed tasks during initialization : " + taskPaths.joinToString( + separator = System.lineSeparator())) + taskPaths.clear() - val (isSuccessful, failure) = server.executeTasks( - TaskExecutionMessage(tasks = listOf("assembleDebug"))).get() + val (isSuccessful, failure) = server.executeTasks( + TaskExecutionMessage(tasks = listOf("assembleDebug"))).get() - if (failure != null) { - println("Failure: $failure") + if (failure != null) { + println("Failure: $failure") + } + + assertThat(isSuccessful).isTrue() + assertThat(failure).isNull() + + assertThat(taskPaths).isNotNull() + assertThat(taskPaths.size).isGreaterThan(10) + assertThat(taskPaths).containsAtLeastElementsIn( + arrayOf("preBuild", "generateDebugResources", "compileDebugJavaWithJavac", + "assembleDebug").map { ":android-library:$it" }) + println( + "Executed tasks during build : " + taskPaths.joinToString(separator = System.lineSeparator())) } - - assertThat(isSuccessful).isTrue() - assertThat(failure).isNull() - - assertThat(taskPaths).isNotNull() - assertThat(taskPaths.size).isGreaterThan(10) - assertThat(taskPaths).containsAtLeastElementsIn( - arrayOf("preBuild", "generateDebugResources", "compileDebugJavaWithJavac", - "assembleDebug").map { ":android-library:$it" }) - println( - "Executed tasks during build : " + taskPaths.joinToString(separator = System.lineSeparator())) - } - - @Test - fun `test project initialization cancellation`() { - // launch project initialization - val (server, _, initFuture) = ToolingApiTestLauncher().launchServerAsync() - Thread.sleep(1000L) - - // cancel initialization request - val cancellationResult = server.cancelCurrentBuild().get() - println("Cancellation result: $cancellationResult") - assertThat(cancellationResult).isNotNull() - assertThat(cancellationResult.wasEnqueued).isTrue() - assertThat(cancellationResult.failureReason).isNull() - - // verify that the initialization failed with reason BUILD_CANCELLED - val initResult = initFuture.get() - assertThat(initResult!!.isSuccessful).isFalse() - assertThat(initResult.failure).isEqualTo(TaskExecutionResult.Failure.BUILD_CANCELLED) } } diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ProjectInitializationCancellationTest.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ProjectInitializationCancellationTest.kt new file mode 100644 index 000000000..ca4b7a458 --- /dev/null +++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/ProjectInitializationCancellationTest.kt @@ -0,0 +1,53 @@ +/* + * 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.tooling.impl + +import com.google.common.truth.Truth.assertThat +import com.itsaky.androidide.testing.tooling.ToolingApiTestLauncher +import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** + * @author Akash Yadav + */ +@RunWith(JUnit4::class) +class ProjectInitializationCancellationTest { + + @Test + fun `test project initialization cancellation`() { + // launch project initialization + ToolingApiTestLauncher.launchServerAsync { + + Thread.sleep(1000L) + + // cancel initialization request + val cancellationResult = server.cancelCurrentBuild().get() + println("Cancellation result: $cancellationResult") + assertThat(cancellationResult).isNotNull() + assertThat(cancellationResult.wasEnqueued).isTrue() + assertThat(cancellationResult.failureReason).isNull() + + // verify that the initialization failed with reason BUILD_CANCELLED + val initResult = initializeResult.get() + assertThat(initResult!!.isSuccessful).isFalse() + assertThat(initResult.failure).isEqualTo(TaskExecutionResult.Failure.BUILD_CANCELLED) + } + } +} \ No newline at end of file diff --git a/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt b/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt index dc2d898b0..ae36674a9 100644 --- a/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt +++ b/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt @@ -85,32 +85,31 @@ abstract class LSPTest { mockkStatic(::tabSize) every { tabSize } returns 4 - val (server, project, result) = - ToolingApiTestLauncher() - .launchServer() + ToolingApiTestLauncher.launchServer { - assertThat(result?.isSuccessful).isTrue() + assertThat(result?.isSuccessful).isTrue() - this.toolingProject = project - this.toolingServer = server + this@LSPTest.toolingProject = project + this@LSPTest.toolingServer = server - Lookup.getDefault().update(BuildService.KEY_PROJECT_PROXY, project) + Lookup.getDefault().update(BuildService.KEY_PROJECT_PROXY, project) - Environment.ANDROID_JAR = FileProvider.resources().resolve("android.jar").toFile() - Environment.JAVA_HOME = File(System.getProperty("java.home")!!) - registerServer() + Environment.ANDROID_JAR = FileProvider.resources().resolve("android.jar").toFile() + Environment.JAVA_HOME = File(System.getProperty("java.home")!!) + registerServer() - val projectManager = ProjectManagerImpl.getInstance() - projectManager.register() - runBlocking { projectManager.setupProject(project) } + val projectManager = ProjectManagerImpl.getInstance() + projectManager.register() + runBlocking { projectManager.setupProject(project) } - // We need to manually setup the language server with the project here - // ProjectManager.notifyProjectUpdate() - ILanguageServerRegistry.getDefault() - .getServer(getServerId())!! - .setupWithProject(projectManager.rootProject!!) + // We need to manually setup the language server with the project here + // ProjectManager.notifyProjectUpdate() + ILanguageServerRegistry.getDefault() + .getServer(getServerId())!! + .setupWithProject(projectManager.rootProject!!) - isInitialized = true + isInitialized = true + } } protected abstract fun registerServer() diff --git a/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/ToolingApiTestLauncher.kt b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/ToolingApiTestLauncher.kt index 00ceff670..630d7f881 100644 --- a/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/ToolingApiTestLauncher.kt +++ b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/ToolingApiTestLauncher.kt @@ -17,6 +17,8 @@ package com.itsaky.androidide.testing.tooling +import com.itsaky.androidide.testing.tooling.models.ToolingApiTestLauncherParams +import com.itsaky.androidide.testing.tooling.models.ToolingApiTestScope import com.itsaky.androidide.tooling.api.IProject import com.itsaky.androidide.tooling.api.IToolingApiClient import com.itsaky.androidide.tooling.api.IToolingApiServer @@ -52,7 +54,7 @@ import kotlin.io.path.pathString * * @author Akash Yadav */ -class ToolingApiTestLauncher { +object ToolingApiTestLauncher { private val opens = mutableMapOf("java.base" to "java.lang", "java.base" to "java.util", @@ -66,46 +68,7 @@ class ToolingApiTestLauncher { "jdk.compiler" to "com.sun.tools.javac.util") @JvmOverloads - fun launchServerAsync( - projectDir: Path = FileProvider.testProjectRoot(), - client: MultiVersionTestClient = MultiVersionTestClient(), - initParams: InitializeProjectParams = InitializeProjectParams( - projectDir.pathString, - client.gradleDistParams - ), - log: ILogger = ILogger.newInstance("BuildOutputLogger"), - sysProps: Map = emptyMap(), - sysEnvs: Map = emptyMap() - ): Triple> { - val cmdLine = createProcessCmd( - FileProvider.implModule() - .resolve("build/libs/tooling-api-all.jar").pathString, - sysProps - ) - - val builder = ProcessBuilder(cmdLine) - val androidHome = findAndroidHome() - - builder.environment()["ANDROID_SDK_ROOT"] = androidHome - builder.environment()["ANDROID_HOME"] = androidHome - builder.environment().putAll(sysEnvs) - - val proc = builder.start() - - Thread(Reader(proc.errorStream, log)).start() - val launcher = - ToolingApiLauncher.newClientLauncher(client, proc.inputStream, - proc.outputStream) - - launcher.startListening() - - val server = launcher.remoteProxy as IToolingApiServer - val project = launcher.remoteProxy as IProject - val result = server.initialize(initParams) - return Triple(server, project, result) - } - - @JvmOverloads + @JvmStatic fun launchServer( projectDir: Path = FileProvider.testProjectRoot(), client: MultiVersionTestClient = MultiVersionTestClient(), @@ -115,10 +78,73 @@ class ToolingApiTestLauncher { ), log: ILogger = ILogger.newInstance("BuildOutputLogger"), sysProps: Map = emptyMap(), - sysEnvs: Map = emptyMap() - ): Triple { - return launchServerAsync(projectDir, client, initParams, log, sysProps, sysEnvs).let { result -> - Triple(result.first, result.second, result.third.get()) + sysEnvs: Map = emptyMap(), + action: ToolingApiTestScope.() -> Unit + ) = launchServer(ToolingApiTestLauncherParams(projectDir, client, initParams, log, sysProps, sysEnvs), action) + + @JvmOverloads + @JvmStatic + @JvmName("launchServerWithParams") + fun launchServer( + params: ToolingApiTestLauncherParams = ToolingApiTestLauncherParams(), + action: ToolingApiTestScope.() -> Unit + ) { + return launchServerAsync(params) { + // wait for project initialization + initializeResult.get() + + action() + } + } + + @JvmOverloads + @JvmStatic + fun launchServerAsync( + params: ToolingApiTestLauncherParams = ToolingApiTestLauncherParams(), + action: ToolingApiTestScope.() -> Unit + ) { + val cmdLine = createProcessCmd( + FileProvider.implModule() + .resolve("build/libs/tooling-api-all.jar").pathString, + params.sysProps + ) + + val builder = ProcessBuilder(cmdLine) + val androidHome = findAndroidHome() + + builder.environment()["ANDROID_SDK_ROOT"] = androidHome + builder.environment()["ANDROID_HOME"] = androidHome + builder.environment().putAll(params.sysEnvs) + + val proc = builder.start() + + proc.onExit().whenComplete { process, error -> + if (process != null) { + println("[ToolingApiTestLauncher] Tooling API server process finished with exit code: ${process.exitValue()}") + } + if (error != null) { + println("[ToolingApiTestLauncher] Tooling API server process error") + error.printStackTrace() + } + } + + Thread(Reader(proc.errorStream, params.log)).start() + val launcher = + ToolingApiLauncher.newClientLauncher(params.client, proc.inputStream, + proc.outputStream) + + launcher.startListening() + + val server = launcher.remoteProxy as IToolingApiServer + val project = launcher.remoteProxy as IProject + val result = server.initialize(params.initParams) + + try { + // perform the action + ToolingApiTestScope(server, project, result).action() + } finally { + server.cancelCurrentBuild().get() + server.shutdown().get() } } diff --git a/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestLauncherParams.kt b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestLauncherParams.kt new file mode 100644 index 000000000..a76bc1f39 --- /dev/null +++ b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestLauncherParams.kt @@ -0,0 +1,42 @@ +/* + * 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.testing.tooling.models + +import com.itsaky.androidide.testing.tooling.ToolingApiTestLauncher +import com.itsaky.androidide.tooling.api.messages.InitializeProjectParams +import com.itsaky.androidide.utils.FileProvider +import com.itsaky.androidide.utils.ILogger +import java.nio.file.Path +import kotlin.io.path.pathString + +/** + * Parameters for launching the tooling API server. + * + * @author Akash Yadav + */ +data class ToolingApiTestLauncherParams( + val projectDir: Path = FileProvider.testProjectRoot(), + val client: ToolingApiTestLauncher.MultiVersionTestClient = ToolingApiTestLauncher.MultiVersionTestClient(), + val initParams: InitializeProjectParams = InitializeProjectParams( + projectDir.pathString, + client.gradleDistParams + ), + val log: ILogger = ILogger.newInstance("BuildOutputLogger"), + val sysProps: Map = emptyMap(), + val sysEnvs: Map = emptyMap() +) \ No newline at end of file diff --git a/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestScope.kt b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestScope.kt new file mode 100644 index 000000000..0c04341d5 --- /dev/null +++ b/testing/tooling/src/main/java/com/itsaky/androidide/testing/tooling/models/ToolingApiTestScope.kt @@ -0,0 +1,38 @@ +/* + * 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.testing.tooling.models + +import com.itsaky.androidide.tooling.api.IProject +import com.itsaky.androidide.tooling.api.IToolingApiServer +import com.itsaky.androidide.tooling.api.messages.result.InitializeResult +import java.util.concurrent.CompletableFuture + +/** + * Scope for Tooling API tests. Provides access to the [IToolingApiServer], [IProject] and the [InitializeResult]. + * + * @author Akash Yadav + */ +class ToolingApiTestScope( + val server: IToolingApiServer, + val project: IProject, + val initializeResult: CompletableFuture +) { + + val result: InitializeResult? + get() = initializeResult.get() +} \ No newline at end of file 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 311fe1959..f3fdd7342 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 @@ -43,13 +43,13 @@ object XmlInflaterTest { return } - val (_, project, result) = - ToolingApiTestLauncher().launchServer() - assertThat(result?.isSuccessful).isTrue() + ToolingApiTestLauncher.launchServer { + assertThat(result?.isSuccessful).isTrue() - Lookup.getDefault().register(BuildService.KEY_PROJECT_PROXY, project) - runBlocking { IProjectManager.getInstance().setupProject(project) } - init.set(true) + Lookup.getDefault().register(BuildService.KEY_PROJECT_PROXY, project) + runBlocking { IProjectManager.getInstance().setupProject(project) } + init.set(true) + } } }