diff --git a/.idea/androidTestResultsUserPreferences.xml b/.idea/androidTestResultsUserPreferences.xml
index 3812fac9d..c235bf396 100644
--- a/.idea/androidTestResultsUserPreferences.xml
+++ b/.idea/androidTestResultsUserPreferences.xml
@@ -31,6 +31,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 63d6992f3..d23437c75 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -116,6 +116,7 @@
+
@@ -128,12 +129,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9e38ced79..fc0930809 100755
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -2,6 +2,7 @@
import androidx.navigation.safe.args.generator.ext.capitalize
import com.android.build.gradle.BaseExtension
+import org.jetbrains.kotlin.gradle.plugin.extraProperties
import java.util.Base64
import java.util.Locale
@@ -162,13 +163,8 @@ dependencies {
// So we always copy the latest JAR file to assets
compileOnly(projects.subprojects.toolingApiImpl)
- testImplementation(libs.common.editor)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.robolectric)
- androidTestImplementation(libs.tests.androidx.junit)
- androidTestImplementation(libs.tests.androidx.espresso)
- androidTestImplementation(libs.tests.google.truth)
+ testImplementation(projects.testing.unit)
+ androidTestImplementation(projects.testing.android)
}
fun downloadSigningKey() {
diff --git a/app/src/androidTest/java/com/itsaky/androidide/activities/MainFragmentTest.kt b/app/src/androidTest/java/com/itsaky/androidide/activities/MainFragmentTest.kt
new file mode 100644
index 000000000..0c8b17349
--- /dev/null
+++ b/app/src/androidTest/java/com/itsaky/androidide/activities/MainFragmentTest.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.activities
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.cardview.widget.CardView
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.*
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.isChecked
+import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withParent
+import androidx.test.espresso.matcher.ViewMatchers.withText
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import com.google.common.truth.Truth.assertThat
+import com.itsaky.androidide.R
+import com.itsaky.androidide.models.MainScreenAction
+import com.itsaky.androidide.templates.BooleanParameter
+import com.itsaky.androidide.templates.EnumParameter
+import com.itsaky.androidide.templates.ITemplateProvider
+import com.itsaky.androidide.templates.StringParameter
+import org.hamcrest.Description
+import org.hamcrest.Matcher
+import org.hamcrest.Matchers.allOf
+import org.hamcrest.TypeSafeMatcher
+import org.hamcrest.core.IsInstanceOf.instanceOf
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class MainFragmentTest {
+
+ @Rule
+ @JvmField
+ var mActivityScenarioRule = ActivityScenarioRule(MainActivity::class.java)
+
+ @Test
+ fun testMainFragmentActionsAreShown() {
+ val recyclerView = onView(allOf(
+ withId(R.id.actions),
+ childAtPosition(
+ withId(R.id.coordinator),
+ 3)))
+
+ recyclerView.check(matches(isDisplayed()))
+
+ for (action in MainScreenAction.all()) {
+ val button = onView(
+ allOf(withText(action.text),
+ withParent(allOf(withId(R.id.actions),
+ withParent(withId(R.id.coordinator)))),
+ isDisplayed()))
+ button.check(matches(isDisplayed()))
+ }
+ }
+
+ @Test
+ fun testTemplateWizardUi() {
+
+ onView(withText(R.string.get_started)).check(matches(isCompletelyDisplayed()))
+
+ val recyclerView = onView(allOf(
+ withId(R.id.actions),
+ childAtPosition(
+ withId(R.id.coordinator),
+ 3)))
+
+ recyclerView.check(matches(isDisplayed()))
+
+ val action = MainScreenAction.all().find { it.id == MainScreenAction.ACTION_CREATE_PROJECT }
+ assertThat(action).isNotNull()
+
+ action!!
+
+ val createProject = onView(allOf(withText(action.text), isDisplayed()))
+
+ createProject.check(matches(isCompletelyDisplayed()))
+ createProject.perform(click())
+
+ val exitButton = onView(
+ allOf(withId(R.id.exit_button), isCompletelyDisplayed())
+ )
+
+ exitButton.check(matches(isCompletelyDisplayed()))
+
+ val templates = ITemplateProvider.getInstance().getTemplates()
+ for (template in templates) {
+ val templateTitle = onView(
+ allOf(withId(R.id.template_name), withText(template.templateName),
+ withParent(
+ withParent(instanceOf(CardView::class.java))),
+ isCompletelyDisplayed()))
+
+ templateTitle.check(matches(isCompletelyDisplayed()))
+ }
+
+ val template = templates.first()
+ val firstTemplateItem = onView(
+ allOf(withId(R.id.template_name), withText(template.templateName),
+ withParent(
+ withParent(instanceOf(CardView::class.java))),
+ isCompletelyDisplayed()))
+
+ firstTemplateItem.perform(click())
+
+ val previousButton = onView(
+ allOf(withId(R.id.previous), withText(R.string.previous), isCompletelyDisplayed()))
+
+ val createProjectFinishButton = onView(
+ allOf(withId(R.id.finish), withText(R.string.create_project),
+ isCompletelyDisplayed()))
+
+ previousButton.check(matches(isCompletelyDisplayed()))
+ createProjectFinishButton.check(matches(isCompletelyDisplayed()))
+
+ for (parameter in template.parameters) {
+ val selector = when (parameter) {
+ is StringParameter -> withText(parameter.value)
+ is BooleanParameter -> allOf(withText(parameter.name),
+ if (parameter.value) isChecked() else isNotChecked())
+
+ is EnumParameter -> withText(parameter.getDisplayName())
+ else -> throw IllegalStateException("Unknown parameter type: $parameter")
+ }
+ val widget = onView(selector)
+ widget.check(matches(isCompletelyDisplayed()))
+ }
+
+ previousButton.perform(click())
+
+ Thread.sleep(1000L)
+
+ exitButton.check(matches(isCompletelyDisplayed()))
+ exitButton.perform(click())
+
+ Thread.sleep(1000L)
+
+ onView(withText(R.string.get_started)).check(matches(isCompletelyDisplayed()))
+ }
+
+ private fun childAtPosition(
+ parentMatcher: Matcher, position: Int): Matcher {
+
+ return object : TypeSafeMatcher() {
+ override fun describeTo(description: Description) {
+ description.appendText("Child at position $position in parent ")
+ parentMatcher.describeTo(description)
+ }
+
+ public override fun matchesSafely(view: View): Boolean {
+ val parent = view.parent
+ return parent is ViewGroup && parentMatcher.matches(parent)
+ && view == parent.getChildAt(position)
+ }
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/itsaky/androidide/adapters/MainActionsListAdapter.kt b/app/src/main/java/com/itsaky/androidide/adapters/MainActionsListAdapter.kt
index 6d768f743..3bf53b69b 100644
--- a/app/src/main/java/com/itsaky/androidide/adapters/MainActionsListAdapter.kt
+++ b/app/src/main/java/com/itsaky/androidide/adapters/MainActionsListAdapter.kt
@@ -47,7 +47,9 @@ constructor(val actions: List = emptyList()) :
binding.root.apply {
setText(action.text)
setIconResource(action.icon)
- setOnClickListener(action.onClick)
+ setOnClickListener {
+ action.onClick?.invoke(action, it)
+ }
}
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
index c50285167..0a916d226 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
+++ b/app/src/main/java/com/itsaky/androidide/fragments/MainFragment.kt
@@ -18,7 +18,6 @@ import com.itsaky.androidide.common.databinding.LayoutDialogProgressBinding
import com.itsaky.androidide.databinding.FragmentMainBinding
import com.itsaky.androidide.models.MainScreenAction
import com.itsaky.androidide.preferences.databinding.LayoutDialogTextInputBinding
-import com.itsaky.androidide.resources.R
import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.tasks.executeAsyncProvideError
import com.itsaky.androidide.utils.DialogUtils
@@ -40,7 +39,7 @@ class MainFragment : BaseFragment() {
private val log = ILogger.newInstance("MainFragment")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
+ savedInstanceState: Bundle?
): View {
binding = FragmentMainBinding.inflate(inflater, container, false)
return binding!!.root
@@ -48,28 +47,26 @@ class MainFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- val createProject = MainScreenAction(string.create_project,
- R.drawable.ic_add) { showCreateProject() }
- val openProject = MainScreenAction(string.msg_open_existing_project,
- R.drawable.ic_folder) { pickDirectory() }
- val cloneGitRepository = MainScreenAction(string.git_clone_repo,
- R.drawable.ic_git) { cloneGitRepo() }
- val openTerminal =
- MainScreenAction(string.title_terminal, R.drawable.ic_terminal) {
- startActivity(Intent(requireActivity(), TerminalActivity::class.java))
+
+ val actions = MainScreenAction.all().also { actions ->
+ val onClick = { action: MainScreenAction, _: View ->
+ when (action.id) {
+ MainScreenAction.ACTION_CREATE_PROJECT -> showCreateProject()
+ MainScreenAction.ACTION_OPEN_PROJECT -> pickDirectory()
+ MainScreenAction.ACTION_CLONE_REPO -> cloneGitRepo()
+ MainScreenAction.ACTION_OPEN_TERMINAL -> startActivity(
+ Intent(requireActivity(), TerminalActivity::class.java))
+
+ MainScreenAction.ACTION_PREFERENCES -> gotoPreferences()
+ MainScreenAction.ACTION_DONATE -> BaseApplication.getBaseInstance().openDonationsPage()
+ MainScreenAction.ACTION_DOCS -> BaseApplication.getBaseInstance().openDocs()
+ }
}
- val preferences = MainScreenAction(string.msg_preferences,
- R.drawable.ic_settings) { gotoPreferences() }
- val sponsor = MainScreenAction(string.btn_donate, R.drawable.ic_donate) {
- BaseApplication.getBaseInstance().openSponsors()
- }
- val docs = MainScreenAction(string.btn_docs, R.drawable.ic_docs) {
- BaseApplication.getBaseInstance().openDocs()
+
+ actions.forEach { action -> action.onClick = onClick }
}
- binding!!.actions.adapter = MainActionsListAdapter(
- listOf(createProject, openProject, cloneGitRepository, openTerminal,
- preferences, docs, sponsor))
+ binding!!.actions.adapter = MainActionsListAdapter(actions)
}
override fun onDestroyView() {
@@ -182,7 +179,7 @@ class MainFragment : BaseFragment() {
// TODO(itsaky) : Improve this implementation
class GitCloneProgressMonitor(val progress: LinearProgressIndicator,
- val message: TextView
+ val message: TextView
) : ProgressMonitor {
private var cancelled = false
diff --git a/app/src/main/java/com/itsaky/androidide/models/MainScreenAction.kt b/app/src/main/java/com/itsaky/androidide/models/MainScreenAction.kt
index 08430ee40..6c78dda71 100644
--- a/app/src/main/java/com/itsaky/androidide/models/MainScreenAction.kt
+++ b/app/src/main/java/com/itsaky/androidide/models/MainScreenAction.kt
@@ -20,6 +20,8 @@ package com.itsaky.androidide.models
import android.view.View
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
+import com.itsaky.androidide.resources.R
+import java.util.Collections
/**
* An action button shown on the main screen.
@@ -28,4 +30,75 @@ import androidx.annotation.StringRes
*/
data class MainScreenAction
@JvmOverloads
-constructor(@StringRes val text: Int, @DrawableRes val icon: Int, val onClick: (View) -> Unit = {})
+constructor(
+ val id: Int,
+ @StringRes val text: Int,
+ @DrawableRes val icon: Int,
+ var onClick: ((MainScreenAction, View) -> Unit)? = null
+) {
+
+ companion object {
+
+ const val ACTION_CREATE_PROJECT = 0
+ const val ACTION_OPEN_PROJECT = 1
+ const val ACTION_CLONE_REPO = 2
+ const val ACTION_OPEN_TERMINAL = 3
+ const val ACTION_PREFERENCES = 4
+ const val ACTION_DONATE = 5
+ const val ACTION_DOCS = 6
+
+ /**
+ * Get all main screen actions.
+ */
+ @JvmStatic
+ fun all(): List {
+ return mutableListOf().apply {
+ val createProject = MainScreenAction(
+ ACTION_CREATE_PROJECT,
+ R.string.create_project,
+ R.drawable.ic_add)
+
+ val openProject = MainScreenAction(
+ ACTION_OPEN_PROJECT,
+ R.string.msg_open_existing_project,
+ R.drawable.ic_folder)
+
+ val cloneGitRepository = MainScreenAction(
+ ACTION_CLONE_REPO,
+ R.string.git_clone_repo,
+ R.drawable.ic_git)
+
+ val openTerminal = MainScreenAction(
+ ACTION_OPEN_TERMINAL,
+ R.string.title_terminal,
+ R.drawable.ic_terminal)
+
+ val preferences = MainScreenAction(
+ ACTION_PREFERENCES,
+ R.string.msg_preferences,
+ R.drawable.ic_settings)
+
+ val donate = MainScreenAction(
+ ACTION_DONATE,
+ R.string.btn_donate,
+ R.drawable.ic_donate
+ )
+
+ val docs = MainScreenAction(
+ ACTION_DOCS,
+ R.string.btn_docs,
+ R.drawable.ic_docs)
+
+ Collections.addAll(this,
+ createProject,
+ openProject,
+ cloneGitRepository,
+ openTerminal,
+ preferences,
+ donate,
+ docs
+ )
+ }
+ }
+ }
+}
diff --git a/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java b/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
index af1d8d1d1..d818acea3 100644
--- a/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
+++ b/common/src/main/java/com/itsaky/androidide/app/BaseApplication.java
@@ -134,7 +134,7 @@ public class BaseApplication extends Application {
openUrl(BuildInfo.PROJECT_SITE);
}
- public void openSponsors() {
+ public void openDonationsPage() {
openUrl(SPONSOR_URL);
}
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 96136c188..6cbf64043 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -13,6 +13,7 @@ androidx-navigation = "2.5.3"
ksp = "1.9.10-1.0.13"
antlr4 = "4.13.1"
androidx-work = "2.8.1"
+androidx-espresso = "3.5.1"
retrofit = "2.9.0"
[libraries]
@@ -113,7 +114,9 @@ tests-androidx-test-runner = { module = "androidx.test:runner", version = "1.5.2
tests-androidx-test-rules = { module = "androidx.test:rules", version = "1.5.0" }
tests-androidx-junit = { module = "androidx.test.ext:junit", version = "1.1.5" }
tests-androidx-work-testing = { module = "androidx.work:work-testing", version.ref = "androidx-work" }
-tests-androidx-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" }
+tests-androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
+tests-androidx-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-espresso" }
+tests-androidx-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.2.0" }
tests-mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "5.1.0" }
tests-mockk = { module = "io.mockk:mockk", version = "1.13.8" }
diff --git a/lsp/java/build.gradle.kts b/lsp/java/build.gradle.kts
index 2ac05b8f4..91a6b238a 100644
--- a/lsp/java/build.gradle.kts
+++ b/lsp/java/build.gradle.kts
@@ -58,15 +58,6 @@ dependencies {
implementation(libs.androidx.ktx)
implementation(libs.common.kotlin)
-
- testImplementation(projects.lsp.testing)
- testImplementation(projects.common)
- testImplementation(projects.actions)
- testImplementation(projects.subprojects.javac)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.robolectric)
- androidTestImplementation(libs.tests.androidx.junit)
- androidTestImplementation(libs.tests.androidx.espresso)
- androidTestImplementation(libs.tests.google.truth)
+
+ testImplementation(projects.testing.lsp)
}
\ No newline at end of file
diff --git a/lsp/xml/build.gradle.kts b/lsp/xml/build.gradle.kts
index 4d77d0749..40ef4ef5f 100644
--- a/lsp/xml/build.gradle.kts
+++ b/lsp/xml/build.gradle.kts
@@ -49,21 +49,12 @@ dependencies {
implementation(libs.androidx.ktx)
implementation(libs.common.kotlin)
implementation(libs.google.material)
-
+
+ testImplementation(projects.actions)
testImplementation(projects.subprojects.projects)
testImplementation(projects.subprojects.toolingApi)
- testImplementation(projects.lsp.testing)
- testImplementation(projects.common)
- testImplementation(projects.actions)
- testImplementation(libs.tests.androidx.test.core)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.robolectric)
- androidTestImplementation(libs.tests.androidx.junit)
- androidTestImplementation(libs.tests.androidx.espresso)
- androidTestImplementation(libs.tests.google.truth)
-
+ testImplementation(projects.testing.lsp)
+
compileOnly(projects.common)
-
compileOnly(libs.common.antlr4)
}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e069455af..d329342cf 100755
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -73,7 +73,6 @@ include(
":lsp:models",
":lsp:java",
":lsp:xml",
- ":lsp:testing",
":subprojects:aaptcompiler",
":subprojects:builder-model-impl",
":subprojects:flashbar",
@@ -94,7 +93,10 @@ include(
":subprojects:tooling-api-events",
":subprojects:tooling-api-impl",
":subprojects:tooling-api-model",
- ":subprojects:tooling-api-testing",
":subprojects:xml-dom",
- ":subprojects:xml-utils"
+ ":subprojects:xml-utils",
+ ":testing:android",
+ ":testing:lsp",
+ ":testing:tooling",
+ ":testing:unit",
)
diff --git a/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt b/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt
index 5321a2aa3..be43ef1b0 100644
--- a/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt
+++ b/shared/src/main/java/com/itsaky/androidide/utils/FileProvider.kt
@@ -62,13 +62,16 @@ class FileProvider {
}
@JvmStatic
- private fun testsDir(): Path = projectRoot().resolve("tests")
+ private fun testingDir() = projectRoot().resolve("testing")
@JvmStatic
- fun testHomeDir(): Path = testsDir().resolve("test-home")
+ private fun testReourcessDir(): Path = testingDir().resolve("resources")
@JvmStatic
- fun testProjectRoot(): Path = testsDir().resolve("test-project")
+ fun testHomeDir(): Path = testReourcessDir().resolve("test-home")
+
+ @JvmStatic
+ fun testProjectRoot(): Path = testReourcessDir().resolve("test-project")
/**
* Get the path to the 'resources' directory.
diff --git a/shared/src/main/java/com/itsaky/androidide/utils/miscUtils.kt b/shared/src/main/java/com/itsaky/androidide/utils/miscUtils.kt
new file mode 100644
index 000000000..ab54698cc
--- /dev/null
+++ b/shared/src/main/java/com/itsaky/androidide/utils/miscUtils.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.utils
+
+@Suppress("UNCHECKED_CAST")
+fun uncheckedCast(obj: Any): T {
+ return obj as T
+}
\ No newline at end of file
diff --git a/subprojects/projects/build.gradle.kts b/subprojects/projects/build.gradle.kts
index 63c93dec5..1e3bdc0d7 100644
--- a/subprojects/projects/build.gradle.kts
+++ b/subprojects/projects/build.gradle.kts
@@ -36,12 +36,5 @@ dependencies {
implementation(libs.google.auto.service.annotations)
implementation(libs.google.guava)
- testImplementation(projects.subprojects.toolingApiTesting)
- testImplementation(projects.shared)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.robolectric)
- androidTestImplementation(libs.tests.androidx.junit)
- androidTestImplementation(libs.tests.androidx.espresso)
- androidTestImplementation(libs.tests.google.truth)
+ testImplementation(projects.testing.tooling)
}
\ No newline at end of file
diff --git a/subprojects/tooling-api-impl/build.gradle.kts b/subprojects/tooling-api-impl/build.gradle.kts
index 971c15fd9..6871c630c 100644
--- a/subprojects/tooling-api-impl/build.gradle.kts
+++ b/subprojects/tooling-api-impl/build.gradle.kts
@@ -55,19 +55,17 @@ project.tasks.getByName("jar") {
project.tasks.getByName("shadowJar") { finalizedBy("copyJar") }
dependencies {
+ api(projects.subprojects.toolingApi)
+
implementation(projects.buildInfo)
implementation(projects.shared)
- implementation(projects.subprojects.toolingApi)
implementation(libs.common.jkotlin)
implementation(libs.xml.xercesImpl)
implementation(libs.xml.apis)
implementation(libs.tooling.gradleApi)
- testImplementation(projects.subprojects.toolingApiTesting)
- testImplementation(projects.shared)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
+ testImplementation(projects.testing.tooling)
runtimeOnly(libs.tooling.slf4j)
}
diff --git a/subprojects/tooling-api-plugin/build.gradle b/subprojects/tooling-api-plugin/build.gradle
deleted file mode 100644
index 598fa74ea..000000000
--- a/subprojects/tooling-api-plugin/build.gradle
+++ /dev/null
@@ -1,73 +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 .
- */
-
-plugins {
- id 'groovy-gradle-plugin'
- id 'maven-publish'
-}
-
-group "com.itsaky.androidide"
-version "1.0.0"
-
-java {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
-}
-
-publishing {
- repositories {
- maven {
- url new File (project.buildDir, "repo")
- }
- }
-}
-
-gradlePlugin {
- plugins {
- androidide {
- id = "com.itsaky.androidide"
- implementationClass = "com.itsaky.androidide.tooling.plugin.AndroidIDEToolingApiPlugin"
- }
- }
-}
-
-task copyToTestDir (type: Copy) {
- from "$project.buildDir.absolutePath/libs/tooling-api-plugin-${version}.jar"
- into "${project.rootProject.file ("tests/test-home/.androidide/init").absolutePath}/"
- rename {
- "plugin.jar"
- }
-
- outputs.upToDateWhen {
- false
- }
-}
-
-project.tasks.jar {
- finalizedBy project.tasks.publish
-}
-
-project.tasks.publish {
- finalizedBy copyToTestDir
- outputs.upToDateWhen {
- false
- }
-}
-
-dependencies {
- implementation project (path: ':subprojects:tooling-api-model')
-}
diff --git a/subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java b/subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java
deleted file mode 100644
index e731a3a6a..000000000
--- a/subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/IdeProjectModelBuilder.java
+++ /dev/null
@@ -1,73 +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.tooling.plugin;
-
-import com.itsaky.androidide.tooling.api.model.IdeProject;
-import com.itsaky.androidide.tooling.api.model.ProjectDependency;
-import com.itsaky.androidide.tooling.api.model.internal.DefaultIdeProject;
-
-import org.gradle.api.Project;
-import org.gradle.tooling.provider.model.ToolingModelBuilder;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Akash Yadav
- */
-public class IdeProjectModelBuilder implements ToolingModelBuilder {
-
- @Override
- public boolean canBuild(String s) {
- return IdeProject.class.getName().equals(s);
- }
-
- @Override
- public Object buildAll(String s, Project project) {
- final var ideProject = new DefaultIdeProject();
- fillProjectDetails(project, ideProject);
- return ideProject;
- }
-
- private void fillProjectDetails(Project project, DefaultIdeProject ideProject) {
- ideProject.setPath(project.getPath());
- ideProject.setDisplayName(project.getDisplayName());
- ideProject.setProjectDir(project.getProjectDir());
- ideProject.setBuildDir(project.getBuildDir());
- ideProject.setBuildFile(project.getBuildFile());
- ideProject.setDependencies(getDependencies(project));
- ideProject.setSubProjects(getSubProjects(project));
- }
-
- private List getDependencies(Project project) {
- return null;
- }
-
- private List getSubProjects(Project project) {
- final var projects = new ArrayList();
- project
- .getSubprojects()
- .forEach(
- sub -> {
- final var subProject = new DefaultIdeProject();
- fillProjectDetails(sub, subProject);
- projects.add(subProject);
- });
- return projects;
- }
-}
diff --git a/subprojects/tooling-api/build.gradle.kts b/subprojects/tooling-api/build.gradle.kts
index 157f249c4..9dd5268ca 100644
--- a/subprojects/tooling-api/build.gradle.kts
+++ b/subprojects/tooling-api/build.gradle.kts
@@ -30,7 +30,4 @@ dependencies {
api(libs.google.gson)
api(libs.common.jsonrpc)
implementation(libs.common.jkotlin)
-
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
}
diff --git a/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt b/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt
index 96ab245dd..17e3f7229 100644
--- a/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt
+++ b/templates-api/src/main/java/com/itsaky/androidide/templates/parameters.kt
@@ -323,7 +323,15 @@ class EnumParameter>(@StringRes name: Int,
val displayName: ((T) -> String)? = null,
val filter: ((T) -> Boolean)? = null
) : TextFieldParameter(name, description, default, startIcon, endIcon,
- onStartIconClick, onEndIconClick, constraints)
+ onStartIconClick, onEndIconClick, constraints) {
+
+ /**
+ * Get the display name for this [EnumParameter].
+ */
+ fun getDisplayName(): String? {
+ return this.displayName?.invoke(value)
+ }
+}
class EnumParameterBuilder> : TextFieldParameterBuilder() {
diff --git a/templates-impl/build.gradle.kts b/templates-impl/build.gradle.kts
index 1a31541ef..da5ea3b38 100644
--- a/templates-impl/build.gradle.kts
+++ b/templates-impl/build.gradle.kts
@@ -38,15 +38,9 @@ dependencies {
implementation(libs.androidx.ktx)
implementation(libs.google.auto.service.annotations)
- testImplementation(projects.common)
testImplementation(projects.templatesApi)
testImplementation(projects.lsp.api)
testImplementation(projects.preferences)
- testImplementation(projects.shared)
- testImplementation(projects.subprojects.toolingApiTesting)
- testImplementation(libs.tests.androidx.test.core)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.mockk)
- testImplementation(libs.tests.robolectric)
+ testImplementation(projects.testing.unit)
+ testImplementation(projects.testing.tooling)
}
\ No newline at end of file
diff --git a/lsp/testing/.gitignore b/testing/android/.gitignore
similarity index 100%
rename from lsp/testing/.gitignore
rename to testing/android/.gitignore
diff --git a/subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/AndroidIDEToolingApiPlugin.java b/testing/android/build.gradle.kts
similarity index 52%
rename from subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/AndroidIDEToolingApiPlugin.java
rename to testing/android/build.gradle.kts
index 49d63c3cc..2d5045115 100644
--- a/subprojects/tooling-api-plugin/src/main/java/com/itsaky/androidide/tooling/plugin/AndroidIDEToolingApiPlugin.java
+++ b/testing/android/build.gradle.kts
@@ -15,29 +15,28 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.tooling.plugin;
-
-import org.gradle.api.Plugin;
-import org.gradle.api.Project;
-import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;
-
-import javax.inject.Inject;
-
-public class AndroidIDEToolingApiPlugin implements Plugin {
-
- private final ToolingModelBuilderRegistry registry;
-
- @Inject
- public AndroidIDEToolingApiPlugin(ToolingModelBuilderRegistry registry) {
- this.registry = registry;
- }
-
- @Override
- public void apply(Project project) {
- if (project != project.getRootProject()) {
- return;
- }
-
- registry.register(new IdeProjectModelBuilder());
- }
+@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+plugins {
+ id("com.android.library")
+ kotlin("android")
}
+
+android {
+ namespace = "${BuildConfig.packageName}.testing.android"
+}
+
+dependencies {
+ api(libs.tests.androidx.test.core)
+ api(libs.tests.androidx.test.runner)
+ api(libs.tests.androidx.test.rules)
+ api(libs.tests.androidx.junit)
+ api(libs.tests.androidx.espresso.core)
+ api(libs.tests.androidx.espresso.contrib)
+ api(libs.tests.androidx.uiautomator)
+ api(libs.tests.junit)
+ api(libs.tests.google.truth)
+
+ api(projects.buildInfo)
+ api(projects.common)
+ api(projects.shared)
+}
\ No newline at end of file
diff --git a/testing/android/consumer-rules.pro b/testing/android/consumer-rules.pro
new file mode 100644
index 000000000..e69de29bb
diff --git a/testing/android/proguard-rules.pro b/testing/android/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/testing/android/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/subprojects/projects/src/androidTest/java/com/itsaky/androidide/projects/ExampleInstrumentedTest.kt b/testing/android/src/main/java/com/itsaky/androidide/testing/android/contextUtils.kt
similarity index 51%
rename from subprojects/projects/src/androidTest/java/com/itsaky/androidide/projects/ExampleInstrumentedTest.kt
rename to testing/android/src/main/java/com/itsaky/androidide/testing/android/contextUtils.kt
index 081dc06be..d2d69a256 100644
--- a/subprojects/projects/src/androidTest/java/com/itsaky/androidide/projects/ExampleInstrumentedTest.kt
+++ b/testing/android/src/main/java/com/itsaky/androidide/testing/android/contextUtils.kt
@@ -15,27 +15,14 @@
* along with AndroidIDE. If not, see .
*/
-package com.itsaky.androidide.projects
+package com.itsaky.androidide.testing.android
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.ext.junit.runners.AndroidJUnit4
-
-import org.junit.Test
-import org.junit.runner.RunWith
-
-import org.junit.Assert.*
+import android.content.Context
+import androidx.annotation.StringRes
+import androidx.test.core.app.ApplicationProvider
/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
+ * Get the value of the string resource.
*/
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("com.itsaky.androidide.projects.test", appContext.packageName)
- }
-}
\ No newline at end of file
+fun stringRes(@StringRes resource: Int, vararg formatArgs: Any) =
+ ApplicationProvider.getApplicationContext().getString(resource, *formatArgs)
\ No newline at end of file
diff --git a/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiAutomatorUtils.kt b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiAutomatorUtils.kt
new file mode 100644
index 000000000..145f626fb
--- /dev/null
+++ b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiAutomatorUtils.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.android
+
+import android.app.Activity
+import android.content.Intent
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
+import androidx.test.runner.lifecycle.Stage
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.google.common.truth.Truth.assertThat
+import com.itsaky.androidide.app.BaseApplication
+import com.itsaky.androidide.buildinfo.BuildInfo
+import com.itsaky.androidide.utils.uncheckedCast
+
+const val LAUNCH_TIMEOUT = 5000L
+
+/**
+ * Launches the AndroidIDE application using UI Automator.
+ *
+ * @param fromLauncher Whether the application must be launched from the Android launcher.
+ * @param clearTasks Whether the application's previous tasks must be cleared.
+ */
+fun launchAndroidIDE(
+ fromLauncher: Boolean = true,
+ clearTasks: Boolean = true,
+): UiDevice {
+ val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+
+ if (fromLauncher) {
+ device.pressHome()
+
+ val launcherPackage = device.launcherPackageName
+ assertThat(launcherPackage).isNotNull()
+
+ device.wait(
+ Until.hasObject(By.pkg(launcherPackage).depth(0)),
+ LAUNCH_TIMEOUT
+ )
+ }
+
+ // Launch the app
+ val context = ApplicationProvider.getApplicationContext()
+ val intent = context.packageManager.getLaunchIntentForPackage(BuildInfo.PACKAGE_NAME)
+ assertThat(intent).isNotNull()
+
+ if (clearTasks) {
+ intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ }
+
+ context.startActivity(intent)
+
+ // Wait for the app to appear
+ device.wait(
+ Until.hasObject(By.pkg(BuildInfo.PACKAGE_NAME).depth(0)),
+ LAUNCH_TIMEOUT
+ )
+
+ return device
+}
+
+/**
+ * Get the first activity in the given [stage].
+ */
+fun getActivityInStage(stage: Stage): T? {
+ var activity: T? = null
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ val activities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(stage)
+ if (activities.isNotEmpty()) {
+ activity = uncheckedCast(activities.first())
+ }
+ }
+
+ return activity
+}
\ No newline at end of file
diff --git a/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiDeviceUtils.kt b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiDeviceUtils.kt
new file mode 100644
index 000000000..93801e734
--- /dev/null
+++ b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiDeviceUtils.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.android
+
+import androidx.annotation.StringRes
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.UiObject2
+import com.itsaky.androidide.buildinfo.BuildInfo
+
+/**
+ * @see UiDevice.waitForWindowUpdate
+ */
+fun UiDevice.waitForWindowUpdate(timeout: Long) =
+ waitForWindowUpdate(BuildInfo.PACKAGE_NAME, timeout)
+
+/**
+ * @see UiDevice.hasObject
+ */
+fun UiDevice.hasObjectWithText(text: String) =
+ hasObject(By.text(text))
+
+/**
+ * @see UiDevice.hasObject
+ */
+fun UiDevice.hasObjectWithText(@StringRes text: Int) =
+ hasObject(By.text(stringRes(text)))
+
+/**
+ * @see UiDevice.findObject
+ */
+fun UiDevice.findObjectWithText(text: String): UiObject2? =
+ findObject(By.text(text))
+
+/**
+ * @see UiDevice.findObjectWithText
+ */
+fun UiDevice.findObjectWithText(@StringRes text: Int): UiObject2? =
+ findObject(By.text(stringRes(text)))
\ No newline at end of file
diff --git a/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiObjectUtils.kt b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiObjectUtils.kt
new file mode 100644
index 000000000..03a725c40
--- /dev/null
+++ b/testing/android/src/main/java/com/itsaky/androidide/testing/android/uiObjectUtils.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.android
+
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.UiObject2
+import androidx.test.uiautomator.Until
+import com.google.common.truth.Truth.assertThat
+
+/**
+ * Click this object and wait for window update with the given timeout duration.
+ *
+ * @see UiDevice.waitForWindowUpdate
+ */
+fun UiObject2?.clickAndWaitForWindowUpdate(device: UiDevice, timeout: Long = 500L) =
+ run {
+ assertThat(this).isNotNull()
+ this!!.click()
+ device.waitForWindowUpdate(timeout)
+ }
+
+/**
+ * Click this object and wait for a new window to appear within the given timeout duration.
+ *
+ * @see UiObject2.clickAndWait
+ */
+fun UiObject2?.clickAndWaitForNewWindow(timeout: Long = LAUNCH_TIMEOUT) =
+ run {
+ assertThat(this).isNotNull()
+ this!!.clickAndWait(Until.newWindow(), timeout)
+ }
\ No newline at end of file
diff --git a/subprojects/tooling-api-plugin/.gitignore b/testing/lsp/.gitignore
similarity index 100%
rename from subprojects/tooling-api-plugin/.gitignore
rename to testing/lsp/.gitignore
diff --git a/lsp/testing/build.gradle.kts b/testing/lsp/build.gradle.kts
similarity index 60%
rename from lsp/testing/build.gradle.kts
rename to testing/lsp/build.gradle.kts
index d06631204..75ee35973 100644
--- a/lsp/testing/build.gradle.kts
+++ b/testing/lsp/build.gradle.kts
@@ -25,19 +25,14 @@ android {
}
dependencies {
- implementation(libs.androidx.ktx)
- implementation(libs.common.kotlin)
+ api(libs.androidx.ktx)
+ api(libs.common.kotlin)
- implementation(projects.lsp.api)
- implementation(projects.actions)
- implementation(projects.common)
- implementation(projects.eventbusAndroid)
- implementation(projects.subprojects.toolingApiTesting)
- implementation(projects.shared)
+ api(projects.lsp.api)
+ api(projects.actions)
+ api(projects.eventbusAndroid)
- implementation(libs.common.editor)
- implementation(libs.tests.junit)
- implementation(libs.tests.google.truth)
- implementation(libs.tests.robolectric)
- implementation(libs.tests.mockk)
+ api(libs.common.editor)
+ api(projects.testing.tooling)
+ api(projects.testing.unit)
}
\ No newline at end of file
diff --git a/lsp/testing/src/main/AndroidManifest.xml b/testing/lsp/src/main/AndroidManifest.xml
similarity index 100%
rename from lsp/testing/src/main/AndroidManifest.xml
rename to testing/lsp/src/main/AndroidManifest.xml
diff --git a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt b/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt
similarity index 100%
rename from lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt
rename to testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/LSPTest.kt
diff --git a/lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/util/ReflectiveLogListener.kt b/testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/util/ReflectiveLogListener.kt
similarity index 100%
rename from lsp/testing/src/main/java/com/itsaky/androidide/lsp/api/util/ReflectiveLogListener.kt
rename to testing/lsp/src/main/java/com/itsaky/androidide/lsp/api/util/ReflectiveLogListener.kt
diff --git a/tests/.gitignore b/testing/resources/.gitignore
similarity index 100%
rename from tests/.gitignore
rename to testing/resources/.gitignore
diff --git a/tests/test-project/.gitignore b/testing/resources/test-project/.gitignore
similarity index 100%
rename from tests/test-project/.gitignore
rename to testing/resources/test-project/.gitignore
diff --git a/tests/test-project/android-library/.gitignore b/testing/resources/test-project/android-library/.gitignore
similarity index 100%
rename from tests/test-project/android-library/.gitignore
rename to testing/resources/test-project/android-library/.gitignore
diff --git a/tests/test-project/android-library/build.gradle b/testing/resources/test-project/android-library/build.gradle
similarity index 100%
rename from tests/test-project/android-library/build.gradle
rename to testing/resources/test-project/android-library/build.gradle
diff --git a/tests/test-project/android-library/src/main/AndroidManifest.xml b/testing/resources/test-project/android-library/src/main/AndroidManifest.xml
similarity index 100%
rename from tests/test-project/android-library/src/main/AndroidManifest.xml
rename to testing/resources/test-project/android-library/src/main/AndroidManifest.xml
diff --git a/tests/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/another-android-library/.gitignore b/testing/resources/test-project/another-android-library/.gitignore
similarity index 100%
rename from tests/test-project/another-android-library/.gitignore
rename to testing/resources/test-project/another-android-library/.gitignore
diff --git a/tests/test-project/another-android-library/build.gradle b/testing/resources/test-project/another-android-library/build.gradle
similarity index 100%
rename from tests/test-project/another-android-library/build.gradle
rename to testing/resources/test-project/another-android-library/build.gradle
diff --git a/tests/test-project/another-android-library/src/main/AndroidManifest.xml b/testing/resources/test-project/another-android-library/src/main/AndroidManifest.xml
similarity index 100%
rename from tests/test-project/another-android-library/src/main/AndroidManifest.xml
rename to testing/resources/test-project/another-android-library/src/main/AndroidManifest.xml
diff --git a/tests/test-project/another-android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/another-android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/another-android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/another-android-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/another-java-library/.gitignore b/testing/resources/test-project/another-java-library/.gitignore
similarity index 100%
rename from tests/test-project/another-java-library/.gitignore
rename to testing/resources/test-project/another-java-library/.gitignore
diff --git a/tests/test-project/another-java-library/build.gradle b/testing/resources/test-project/another-java-library/build.gradle
similarity index 100%
rename from tests/test-project/another-java-library/build.gradle
rename to testing/resources/test-project/another-java-library/build.gradle
diff --git a/tests/test-project/another-java-library/nested-java-library/.gitignore b/testing/resources/test-project/another-java-library/nested-java-library/.gitignore
similarity index 100%
rename from tests/test-project/another-java-library/nested-java-library/.gitignore
rename to testing/resources/test-project/another-java-library/nested-java-library/.gitignore
diff --git a/tests/test-project/another-java-library/nested-java-library/build.gradle b/testing/resources/test-project/another-java-library/nested-java-library/build.gradle
similarity index 100%
rename from tests/test-project/another-java-library/nested-java-library/build.gradle
rename to testing/resources/test-project/another-java-library/nested-java-library/build.gradle
diff --git a/tests/test-project/another-java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/another-java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/another-java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/another-java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/another-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/another-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/another-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/another-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/app/.gitignore b/testing/resources/test-project/app/.gitignore
similarity index 100%
rename from tests/test-project/app/.gitignore
rename to testing/resources/test-project/app/.gitignore
diff --git a/tests/test-project/app/build.gradle.in b/testing/resources/test-project/app/build.gradle.in
similarity index 100%
rename from tests/test-project/app/build.gradle.in
rename to testing/resources/test-project/app/build.gradle.in
diff --git a/tests/test-project/app/proguard-rules.pro b/testing/resources/test-project/app/proguard-rules.pro
similarity index 100%
rename from tests/test-project/app/proguard-rules.pro
rename to testing/resources/test-project/app/proguard-rules.pro
diff --git a/tests/test-project/app/src/main/AndroidManifest.xml b/testing/resources/test-project/app/src/main/AndroidManifest.xml
similarity index 100%
rename from tests/test-project/app/src/main/AndroidManifest.xml
rename to testing/resources/test-project/app/src/main/AndroidManifest.xml
diff --git a/tests/test-project/app/src/main/java/com/itsaky/test/app/MainActivity.java b/testing/resources/test-project/app/src/main/java/com/itsaky/test/app/MainActivity.java
similarity index 100%
rename from tests/test-project/app/src/main/java/com/itsaky/test/app/MainActivity.java
rename to testing/resources/test-project/app/src/main/java/com/itsaky/test/app/MainActivity.java
diff --git a/tests/test-project/app/src/main/res/anim/TestSimpleAttrValue_template.xml b/testing/resources/test-project/app/src/main/res/anim/TestSimpleAttrValue_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/anim/TestSimpleAttrValue_template.xml
rename to testing/resources/test-project/app/src/main/res/anim/TestSimpleAttrValue_template.xml
diff --git a/tests/test-project/app/src/main/res/anim/TestSimpleAttributes_template.xml b/testing/resources/test-project/app/src/main/res/anim/TestSimpleAttributes_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/anim/TestSimpleAttributes_template.xml
rename to testing/resources/test-project/app/src/main/res/anim/TestSimpleAttributes_template.xml
diff --git a/tests/test-project/app/src/main/res/color/test_selector.xml b/testing/resources/test-project/app/src/main/res/color/test_selector.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/color/test_selector.xml
rename to testing/resources/test-project/app/src/main/res/color/test_selector.xml
diff --git a/tests/test-project/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/testing/resources/test-project/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
rename to testing/resources/test-project/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
diff --git a/tests/test-project/app/src/main/res/drawable/TestDrawableAttrValue_template.xml b/testing/resources/test-project/app/src/main/res/drawable/TestDrawableAttrValue_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/drawable/TestDrawableAttrValue_template.xml
rename to testing/resources/test-project/app/src/main/res/drawable/TestDrawableAttrValue_template.xml
diff --git a/tests/test-project/app/src/main/res/drawable/TestDrawableAttrs_template.xml b/testing/resources/test-project/app/src/main/res/drawable/TestDrawableAttrs_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/drawable/TestDrawableAttrs_template.xml
rename to testing/resources/test-project/app/src/main/res/drawable/TestDrawableAttrs_template.xml
diff --git a/tests/test-project/app/src/main/res/drawable/ic_launcher_background.xml b/testing/resources/test-project/app/src/main/res/drawable/ic_launcher_background.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/drawable/ic_launcher_background.xml
rename to testing/resources/test-project/app/src/main/res/drawable/ic_launcher_background.xml
diff --git a/tests/test-project/app/src/main/res/layout/AbsoluteLayout.xml b/testing/resources/test-project/app/src/main/res/layout/AbsoluteLayout.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/AbsoluteLayout.xml
rename to testing/resources/test-project/app/src/main/res/layout/AbsoluteLayout.xml
diff --git a/tests/test-project/app/src/main/res/layout/AttributeCompletion_template.xml b/testing/resources/test-project/app/src/main/res/layout/AttributeCompletion_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/AttributeCompletion_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/AttributeCompletion_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/AttributeValueCompletion_template.xml b/testing/resources/test-project/app/src/main/res/layout/AttributeValueCompletion_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/AttributeValueCompletion_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/AttributeValueCompletion_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/AutoCompleteTextView.xml b/testing/resources/test-project/app/src/main/res/layout/AutoCompleteTextView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/AutoCompleteTextView.xml
rename to testing/resources/test-project/app/src/main/res/layout/AutoCompleteTextView.xml
diff --git a/tests/test-project/app/src/main/res/layout/Button.xml b/testing/resources/test-project/app/src/main/res/layout/Button.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/Button.xml
rename to testing/resources/test-project/app/src/main/res/layout/Button.xml
diff --git a/tests/test-project/app/src/main/res/layout/CheckBox.xml b/testing/resources/test-project/app/src/main/res/layout/CheckBox.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/CheckBox.xml
rename to testing/resources/test-project/app/src/main/res/layout/CheckBox.xml
diff --git a/tests/test-project/app/src/main/res/layout/CheckedTextView.xml b/testing/resources/test-project/app/src/main/res/layout/CheckedTextView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/CheckedTextView.xml
rename to testing/resources/test-project/app/src/main/res/layout/CheckedTextView.xml
diff --git a/tests/test-project/app/src/main/res/layout/ConstantDimensionTest_template.xml b/testing/resources/test-project/app/src/main/res/layout/ConstantDimensionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ConstantDimensionTest_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/ConstantDimensionTest_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/EditText.xml b/testing/resources/test-project/app/src/main/res/layout/EditText.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/EditText.xml
rename to testing/resources/test-project/app/src/main/res/layout/EditText.xml
diff --git a/tests/test-project/app/src/main/res/layout/EmptyTagNameCompletion_template.xml b/testing/resources/test-project/app/src/main/res/layout/EmptyTagNameCompletion_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/EmptyTagNameCompletion_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/EmptyTagNameCompletion_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/FrameLayout.xml b/testing/resources/test-project/app/src/main/res/layout/FrameLayout.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/FrameLayout.xml
rename to testing/resources/test-project/app/src/main/res/layout/FrameLayout.xml
diff --git a/tests/test-project/app/src/main/res/layout/GestureOverlayView.xml b/testing/resources/test-project/app/src/main/res/layout/GestureOverlayView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/GestureOverlayView.xml
rename to testing/resources/test-project/app/src/main/res/layout/GestureOverlayView.xml
diff --git a/tests/test-project/app/src/main/res/layout/GridLayout.xml b/testing/resources/test-project/app/src/main/res/layout/GridLayout.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/GridLayout.xml
rename to testing/resources/test-project/app/src/main/res/layout/GridLayout.xml
diff --git a/tests/test-project/app/src/main/res/layout/ImageButton.xml b/testing/resources/test-project/app/src/main/res/layout/ImageButton.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ImageButton.xml
rename to testing/resources/test-project/app/src/main/res/layout/ImageButton.xml
diff --git a/tests/test-project/app/src/main/res/layout/ImageView.xml b/testing/resources/test-project/app/src/main/res/layout/ImageView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ImageView.xml
rename to testing/resources/test-project/app/src/main/res/layout/ImageView.xml
diff --git a/tests/test-project/app/src/main/res/layout/LinearLayout.xml b/testing/resources/test-project/app/src/main/res/layout/LinearLayout.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/LinearLayout.xml
rename to testing/resources/test-project/app/src/main/res/layout/LinearLayout.xml
diff --git a/tests/test-project/app/src/main/res/layout/ListView.xml b/testing/resources/test-project/app/src/main/res/layout/ListView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ListView.xml
rename to testing/resources/test-project/app/src/main/res/layout/ListView.xml
diff --git a/tests/test-project/app/src/main/res/layout/ProgressBar.xml b/testing/resources/test-project/app/src/main/res/layout/ProgressBar.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ProgressBar.xml
rename to testing/resources/test-project/app/src/main/res/layout/ProgressBar.xml
diff --git a/tests/test-project/app/src/main/res/layout/RadioButton.xml b/testing/resources/test-project/app/src/main/res/layout/RadioButton.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/RadioButton.xml
rename to testing/resources/test-project/app/src/main/res/layout/RadioButton.xml
diff --git a/tests/test-project/app/src/main/res/layout/RelativeLayout.xml b/testing/resources/test-project/app/src/main/res/layout/RelativeLayout.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/RelativeLayout.xml
rename to testing/resources/test-project/app/src/main/res/layout/RelativeLayout.xml
diff --git a/tests/test-project/app/src/main/res/layout/SeekBar.xml b/testing/resources/test-project/app/src/main/res/layout/SeekBar.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/SeekBar.xml
rename to testing/resources/test-project/app/src/main/res/layout/SeekBar.xml
diff --git a/tests/test-project/app/src/main/res/layout/Spinner.xml b/testing/resources/test-project/app/src/main/res/layout/Spinner.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/Spinner.xml
rename to testing/resources/test-project/app/src/main/res/layout/Spinner.xml
diff --git a/tests/test-project/app/src/main/res/layout/SurfaceView.xml b/testing/resources/test-project/app/src/main/res/layout/SurfaceView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/SurfaceView.xml
rename to testing/resources/test-project/app/src/main/res/layout/SurfaceView.xml
diff --git a/tests/test-project/app/src/main/res/layout/Switch.xml b/testing/resources/test-project/app/src/main/res/layout/Switch.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/Switch.xml
rename to testing/resources/test-project/app/src/main/res/layout/Switch.xml
diff --git a/tests/test-project/app/src/main/res/layout/TagCompletion_template.xml b/testing/resources/test-project/app/src/main/res/layout/TagCompletion_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TagCompletion_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TagCompletion_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueFromNamespaceAuto_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueFromNamespaceAuto_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueFromNamespaceAuto_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueFromNamespaceAuto_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueFromNamespace_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueFromNamespace_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueFromNamespace_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueFromNamespace_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix2_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix2_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix2_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix2_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefPrefix_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompletePck_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompletePck_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompletePck_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompletePck_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteTypeOrPck_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteTypeOrPck_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteTypeOrPck_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteTypeOrPck_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteType_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteType_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteType_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithQualifiedRefWithIncompleteType_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrValueWithRefPrefix_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithRefPrefix_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrValueWithRefPrefix_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrValueWithRefPrefix_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsFromLayoutParams_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsFromLayoutParams_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsFromLayoutParams_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsFromLayoutParams_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsFromSuperclass_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsFromSuperclass_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsFromSuperclass_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsFromSuperclass_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsRefValue_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsRefValue_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsRefValue_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsRefValue_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsValue_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsValue_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsValue_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsValue_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespaceAuto_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespaceAuto_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespaceAuto_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespaceAuto_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespace_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespace_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespace_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithDefinedNamespace_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespacesAuto_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespacesAuto_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespacesAuto_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespacesAuto_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespaces_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespaces_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespaces_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithMultipleNamespaces_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithNamespace_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithNamespace_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithNamespace_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithNamespace_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestAttrsWithPartialName_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestAttrsWithPartialName_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestAttrsWithPartialName_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestAttrsWithPartialName_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TestNoDuplicateAttrs_template.xml b/testing/resources/test-project/app/src/main/res/layout/TestNoDuplicateAttrs_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TestNoDuplicateAttrs_template.xml
rename to testing/resources/test-project/app/src/main/res/layout/TestNoDuplicateAttrs_template.xml
diff --git a/tests/test-project/app/src/main/res/layout/TextView.xml b/testing/resources/test-project/app/src/main/res/layout/TextView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TextView.xml
rename to testing/resources/test-project/app/src/main/res/layout/TextView.xml
diff --git a/tests/test-project/app/src/main/res/layout/TextureView.xml b/testing/resources/test-project/app/src/main/res/layout/TextureView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/TextureView.xml
rename to testing/resources/test-project/app/src/main/res/layout/TextureView.xml
diff --git a/tests/test-project/app/src/main/res/layout/ToggleButton.xml b/testing/resources/test-project/app/src/main/res/layout/ToggleButton.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/ToggleButton.xml
rename to testing/resources/test-project/app/src/main/res/layout/ToggleButton.xml
diff --git a/tests/test-project/app/src/main/res/layout/View.xml b/testing/resources/test-project/app/src/main/res/layout/View.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/View.xml
rename to testing/resources/test-project/app/src/main/res/layout/View.xml
diff --git a/tests/test-project/app/src/main/res/layout/WebView.xml b/testing/resources/test-project/app/src/main/res/layout/WebView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/WebView.xml
rename to testing/resources/test-project/app/src/main/res/layout/WebView.xml
diff --git a/tests/test-project/app/src/main/res/layout/activity_main.xml b/testing/resources/test-project/app/src/main/res/layout/activity_main.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/activity_main.xml
rename to testing/resources/test-project/app/src/main/res/layout/activity_main.xml
diff --git a/tests/test-project/app/src/main/res/layout/include.xml b/testing/resources/test-project/app/src/main/res/layout/include.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/include.xml
rename to testing/resources/test-project/app/src/main/res/layout/include.xml
diff --git a/tests/test-project/app/src/main/res/layout/include_order.xml b/testing/resources/test-project/app/src/main/res/layout/include_order.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/include_order.xml
rename to testing/resources/test-project/app/src/main/res/layout/include_order.xml
diff --git a/tests/test-project/app/src/main/res/layout/inlined.xml b/testing/resources/test-project/app/src/main/res/layout/inlined.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/inlined.xml
rename to testing/resources/test-project/app/src/main/res/layout/inlined.xml
diff --git a/tests/test-project/app/src/main/res/layout/layout_include.xml b/testing/resources/test-project/app/src/main/res/layout/layout_include.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/layout_include.xml
rename to testing/resources/test-project/app/src/main/res/layout/layout_include.xml
diff --git a/tests/test-project/app/src/main/res/layout/layout_merge.xml b/testing/resources/test-project/app/src/main/res/layout/layout_merge.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/layout_merge.xml
rename to testing/resources/test-project/app/src/main/res/layout/layout_merge.xml
diff --git a/tests/test-project/app/src/main/res/layout/merge.xml b/testing/resources/test-project/app/src/main/res/layout/merge.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/merge.xml
rename to testing/resources/test-project/app/src/main/res/layout/merge.xml
diff --git a/tests/test-project/app/src/main/res/layout/singleView.xml b/testing/resources/test-project/app/src/main/res/layout/singleView.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/singleView.xml
rename to testing/resources/test-project/app/src/main/res/layout/singleView.xml
diff --git a/tests/test-project/app/src/main/res/layout/unsupported_views.xml b/testing/resources/test-project/app/src/main/res/layout/unsupported_views.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/layout/unsupported_views.xml
rename to testing/resources/test-project/app/src/main/res/layout/unsupported_views.xml
diff --git a/tests/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/testing/resources/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
rename to testing/resources/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
diff --git a/tests/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/testing/resources/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
rename to testing/resources/test-project/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
diff --git a/tests/test-project/app/src/main/res/mipmap-hdpi/ic_launcher.png b/testing/resources/test-project/app/src/main/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-hdpi/ic_launcher.png
rename to testing/resources/test-project/app/src/main/res/mipmap-hdpi/ic_launcher.png
diff --git a/tests/test-project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/testing/resources/test-project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
rename to testing/resources/test-project/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
diff --git a/tests/test-project/app/src/main/res/mipmap-mdpi/ic_launcher.png b/testing/resources/test-project/app/src/main/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-mdpi/ic_launcher.png
rename to testing/resources/test-project/app/src/main/res/mipmap-mdpi/ic_launcher.png
diff --git a/tests/test-project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/testing/resources/test-project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
rename to testing/resources/test-project/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/testing/resources/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/testing/resources/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/testing/resources/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/testing/resources/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/testing/resources/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
diff --git a/tests/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/testing/resources/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
similarity index 100%
rename from tests/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
rename to testing/resources/test-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
diff --git a/tests/test-project/app/src/main/res/transition/TestSimpleAttrValue_template.xml b/testing/resources/test-project/app/src/main/res/transition/TestSimpleAttrValue_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/transition/TestSimpleAttrValue_template.xml
rename to testing/resources/test-project/app/src/main/res/transition/TestSimpleAttrValue_template.xml
diff --git a/tests/test-project/app/src/main/res/transition/TestSimpleAttributes_template.xml b/testing/resources/test-project/app/src/main/res/transition/TestSimpleAttributes_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/transition/TestSimpleAttributes_template.xml
rename to testing/resources/test-project/app/src/main/res/transition/TestSimpleAttributes_template.xml
diff --git a/tests/test-project/app/src/main/res/values/colors.xml b/testing/resources/test-project/app/src/main/res/values/colors.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/values/colors.xml
rename to testing/resources/test-project/app/src/main/res/values/colors.xml
diff --git a/tests/test-project/app/src/main/res/values/parser_test.xml b/testing/resources/test-project/app/src/main/res/values/parser_test.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/values/parser_test.xml
rename to testing/resources/test-project/app/src/main/res/values/parser_test.xml
diff --git a/tests/test-project/app/src/main/res/values/strings.xml b/testing/resources/test-project/app/src/main/res/values/strings.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/values/strings.xml
rename to testing/resources/test-project/app/src/main/res/values/strings.xml
diff --git a/tests/test-project/app/src/main/res/values/styles.xml b/testing/resources/test-project/app/src/main/res/values/styles.xml
similarity index 100%
rename from tests/test-project/app/src/main/res/values/styles.xml
rename to testing/resources/test-project/app/src/main/res/values/styles.xml
diff --git a/tests/test-project/app/src/main/resources/SourceFileTest_tempate.xml b/testing/resources/test-project/app/src/main/resources/SourceFileTest_tempate.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/SourceFileTest_tempate.xml
rename to testing/resources/test-project/app/src/main/resources/SourceFileTest_tempate.xml
diff --git a/tests/test-project/app/src/main/resources/SourceFileTest_template.java b/testing/resources/test-project/app/src/main/resources/SourceFileTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/SourceFileTest_template.java
rename to testing/resources/test-project/app/src/main/resources/SourceFileTest_template.java
diff --git a/tests/test-project/app/src/main/resources/actions/AddImportAction_template.java b/testing/resources/test-project/app/src/main/resources/actions/AddImportAction_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/actions/AddImportAction_template.java
rename to testing/resources/test-project/app/src/main/resources/actions/AddImportAction_template.java
diff --git a/tests/test-project/app/src/main/resources/actions/GenerateSettersAndGettersTest_template.java b/testing/resources/test-project/app/src/main/resources/actions/GenerateSettersAndGettersTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/actions/GenerateSettersAndGettersTest_template.java
rename to testing/resources/test-project/app/src/main/resources/actions/GenerateSettersAndGettersTest_template.java
diff --git a/tests/test-project/app/src/main/resources/android.jar b/testing/resources/test-project/app/src/main/resources/android.jar
similarity index 100%
rename from tests/test-project/app/src/main/resources/android.jar
rename to testing/resources/test-project/app/src/main/resources/android.jar
diff --git a/tests/test-project/app/src/main/resources/completion/LambdaMembersCompletionTest_template.java b/testing/resources/test-project/app/src/main/resources/completion/LambdaMembersCompletionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/LambdaMembersCompletionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/completion/LambdaMembersCompletionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/completion/LocalsCompletionTest_template.java b/testing/resources/test-project/app/src/main/resources/completion/LocalsCompletionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/LocalsCompletionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/completion/LocalsCompletionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestActivityActionCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestActivityActionCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestActivityActionCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestActivityActionCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestApplicationAttrTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestApplicationAttrTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestApplicationAttrTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestApplicationAttrTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestAttrTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestAttrTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestAttrTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestAttrTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestAttrValueTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestAttrValueTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestAttrValueTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestAttrValueTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestCategoryCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestCategoryCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestCategoryCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestCategoryCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestFeatureCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestFeatureCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestFeatureCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestFeatureCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestPermTagTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestPermTagTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestPermTagTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestPermTagTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestPermissionCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestPermissionCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestPermissionCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestPermissionCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestReceiverActionCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestReceiverActionCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestReceiverActionCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestReceiverActionCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestResourceReferenceCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestResourceReferenceCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestResourceReferenceCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestResourceReferenceCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestServiceActionCompletionTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestServiceActionCompletionTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestServiceActionCompletionTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestServiceActionCompletionTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/ManifestUsesTagTest_template.xml b/testing/resources/test-project/app/src/main/resources/completion/ManifestUsesTagTest_template.xml
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/ManifestUsesTagTest_template.xml
rename to testing/resources/test-project/app/src/main/resources/completion/ManifestUsesTagTest_template.xml
diff --git a/tests/test-project/app/src/main/resources/completion/MembersCompletionTest_template.java b/testing/resources/test-project/app/src/main/resources/completion/MembersCompletionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/MembersCompletionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/completion/MembersCompletionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/completion/StaticMembersCompletionTest_template.java b/testing/resources/test-project/app/src/main/resources/completion/StaticMembersCompletionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/completion/StaticMembersCompletionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/completion/StaticMembersCompletionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/package/SourceFileTest_template.java b/testing/resources/test-project/app/src/main/resources/package/SourceFileTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/package/SourceFileTest_template.java
rename to testing/resources/test-project/app/src/main/resources/package/SourceFileTest_template.java
diff --git a/tests/test-project/app/src/main/resources/partial/PartialErrReparserTest_template.java b/testing/resources/test-project/app/src/main/resources/partial/PartialErrReparserTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/partial/PartialErrReparserTest_template.java
rename to testing/resources/test-project/app/src/main/resources/partial/PartialErrReparserTest_template.java
diff --git a/tests/test-project/app/src/main/resources/partial/PartialReparserTest_template.java b/testing/resources/test-project/app/src/main/resources/partial/PartialReparserTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/partial/PartialReparserTest_template.java
rename to testing/resources/test-project/app/src/main/resources/partial/PartialReparserTest_template.java
diff --git a/tests/test-project/app/src/main/resources/selection/MethodBodySelectionExpansionTest_template.java b/testing/resources/test-project/app/src/main/resources/selection/MethodBodySelectionExpansionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/selection/MethodBodySelectionExpansionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/selection/MethodBodySelectionExpansionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/selection/SimpleSelectionExpansionTest_template.java b/testing/resources/test-project/app/src/main/resources/selection/SimpleSelectionExpansionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/selection/SimpleSelectionExpansionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/selection/SimpleSelectionExpansionTest_template.java
diff --git a/tests/test-project/app/src/main/resources/selection/TrySelectionExpansionTest_template.java b/testing/resources/test-project/app/src/main/resources/selection/TrySelectionExpansionTest_template.java
similarity index 100%
rename from tests/test-project/app/src/main/resources/selection/TrySelectionExpansionTest_template.java
rename to testing/resources/test-project/app/src/main/resources/selection/TrySelectionExpansionTest_template.java
diff --git a/tests/test-project/build.gradle.in b/testing/resources/test-project/build.gradle.in
similarity index 100%
rename from tests/test-project/build.gradle.in
rename to testing/resources/test-project/build.gradle.in
diff --git a/tests/test-project/gradle.properties b/testing/resources/test-project/gradle.properties
similarity index 100%
rename from tests/test-project/gradle.properties
rename to testing/resources/test-project/gradle.properties
diff --git a/tests/test-project/gradle/wrapper/.gitignore b/testing/resources/test-project/gradle/wrapper/.gitignore
similarity index 100%
rename from tests/test-project/gradle/wrapper/.gitignore
rename to testing/resources/test-project/gradle/wrapper/.gitignore
diff --git a/tests/test-project/gradle/wrapper/gradle-wrapper.jar b/testing/resources/test-project/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from tests/test-project/gradle/wrapper/gradle-wrapper.jar
rename to testing/resources/test-project/gradle/wrapper/gradle-wrapper.jar
diff --git a/tests/test-project/gradle/wrapper/gradle-wrapper.properties.in b/testing/resources/test-project/gradle/wrapper/gradle-wrapper.properties.in
similarity index 100%
rename from tests/test-project/gradle/wrapper/gradle-wrapper.properties.in
rename to testing/resources/test-project/gradle/wrapper/gradle-wrapper.properties.in
diff --git a/tests/test-project/gradlew b/testing/resources/test-project/gradlew
similarity index 100%
rename from tests/test-project/gradlew
rename to testing/resources/test-project/gradlew
diff --git a/tests/test-project/gradlew.bat b/testing/resources/test-project/gradlew.bat
similarity index 100%
rename from tests/test-project/gradlew.bat
rename to testing/resources/test-project/gradlew.bat
diff --git a/tests/test-project/java-library/.gitignore b/testing/resources/test-project/java-library/.gitignore
similarity index 100%
rename from tests/test-project/java-library/.gitignore
rename to testing/resources/test-project/java-library/.gitignore
diff --git a/tests/test-project/java-library/build.gradle b/testing/resources/test-project/java-library/build.gradle
similarity index 100%
rename from tests/test-project/java-library/build.gradle
rename to testing/resources/test-project/java-library/build.gradle
diff --git a/tests/test-project/java-library/nested-java-library/.gitignore b/testing/resources/test-project/java-library/nested-java-library/.gitignore
similarity index 100%
rename from tests/test-project/java-library/nested-java-library/.gitignore
rename to testing/resources/test-project/java-library/nested-java-library/.gitignore
diff --git a/tests/test-project/java-library/nested-java-library/build.gradle b/testing/resources/test-project/java-library/nested-java-library/build.gradle
similarity index 100%
rename from tests/test-project/java-library/nested-java-library/build.gradle
rename to testing/resources/test-project/java-library/nested-java-library/build.gradle
diff --git a/tests/test-project/java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/java-library/nested-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/other-java-library/.gitignore b/testing/resources/test-project/other-java-library/.gitignore
similarity index 100%
rename from tests/test-project/other-java-library/.gitignore
rename to testing/resources/test-project/other-java-library/.gitignore
diff --git a/tests/test-project/other-java-library/build.gradle b/testing/resources/test-project/other-java-library/build.gradle
similarity index 100%
rename from tests/test-project/other-java-library/build.gradle
rename to testing/resources/test-project/other-java-library/build.gradle
diff --git a/tests/test-project/other-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java b/testing/resources/test-project/other-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
similarity index 100%
rename from tests/test-project/other-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
rename to testing/resources/test-project/other-java-library/src/main/java/com/itsaky/androidide/tooling/test/Main.java
diff --git a/tests/test-project/settings.gradle b/testing/resources/test-project/settings.gradle
similarity index 100%
rename from tests/test-project/settings.gradle
rename to testing/resources/test-project/settings.gradle
diff --git a/subprojects/tooling-api-testing/.gitignore b/testing/tooling/.gitignore
similarity index 100%
rename from subprojects/tooling-api-testing/.gitignore
rename to testing/tooling/.gitignore
diff --git a/subprojects/tooling-api-testing/build.gradle.kts b/testing/tooling/build.gradle.kts
similarity index 77%
rename from subprojects/tooling-api-testing/build.gradle.kts
rename to testing/tooling/build.gradle.kts
index 6f3b4e9e9..417b42a4d 100644
--- a/subprojects/tooling-api-testing/build.gradle.kts
+++ b/testing/tooling/build.gradle.kts
@@ -22,10 +22,16 @@ plugins {
}
dependencies {
- implementation(libs.common.jkotlin)
- implementation(projects.logger)
- implementation(projects.subprojects.toolingApi)
- implementation(projects.shared)
+ api(libs.common.jkotlin)
+ api(libs.tests.robolectric)
+ api(libs.tests.junit)
+ api(libs.tests.google.truth)
+ api(libs.tests.mockk)
+
+ api(projects.buildInfo)
+ api(projects.logger)
+ api(projects.shared)
+ api(projects.subprojects.toolingApi)
// build tooling API before tests
compileOnly(projects.subprojects.toolingApiImpl)
diff --git a/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt b/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
similarity index 100%
rename from subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
rename to testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/ToolingApiTestLauncher.kt
diff --git a/subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/utils.kt b/testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/utils.kt
similarity index 100%
rename from subprojects/tooling-api-testing/src/main/java/com/itsaky/androidide/tooling/testing/utils.kt
rename to testing/tooling/src/main/java/com/itsaky/androidide/tooling/testing/utils.kt
diff --git a/testing/unit/.gitignore b/testing/unit/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/testing/unit/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/testing/unit/build.gradle.kts b/testing/unit/build.gradle.kts
new file mode 100644
index 000000000..347f1c4e2
--- /dev/null
+++ b/testing/unit/build.gradle.kts
@@ -0,0 +1,37 @@
+/*
+ * 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 .
+ */
+
+plugins {
+ id("com.android.library")
+ kotlin("android")
+}
+
+android {
+ namespace = "${BuildConfig.packageName}.testing.unit"
+}
+
+dependencies {
+ api(libs.tests.androidx.test.core)
+ api(libs.tests.robolectric)
+ api(libs.tests.junit)
+ api(libs.tests.google.truth)
+ api(libs.tests.mockk)
+
+ api(projects.buildInfo)
+ api(projects.common)
+ api(projects.shared)
+}
\ No newline at end of file
diff --git a/testing/unit/consumer-rules.pro b/testing/unit/consumer-rules.pro
new file mode 100644
index 000000000..e69de29bb
diff --git a/testing/unit/proguard-rules.pro b/testing/unit/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/testing/unit/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/tests/test-home/.androidide/.gitignore b/tests/test-home/.androidide/.gitignore
deleted file mode 100644
index aec8cfdc7..000000000
--- a/tests/test-home/.androidide/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/init
diff --git a/tests/test-project/app/build.gradle b/tests/test-project/app/build.gradle
deleted file mode 100644
index d6976bc2e..000000000
--- a/tests/test-project/app/build.gradle
+++ /dev/null
@@ -1,75 +0,0 @@
-// DO NOT EDIT - Automatically generated file
-
-plugins {
- id 'com.android.application'
-}
-
-android {
- namespace = "com.itsaky.test.app"
- compileSdkVersion rootProject.ext.compileSdk
- buildToolsVersion rootProject.ext.buildTools
-
- defaultConfig {
- applicationId rootProject.ext.appId
- minSdkVersion rootProject.ext.minSdk
- targetSdkVersion rootProject.ext.targetSdk
- versionCode rootProject.ext.versionCode
- versionName rootProject.ext.versionName
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile ('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
- }
-
- lintOptions {
- abortOnError false
- }
-
- buildFeatures {
- viewBinding true
- }
-}
-
-task thisIsATestTask () {
- println "This is a test task"
-}
-
-dependencies {
- implementation fileTree (dir: "libs", include: ["*.jar"])
- implementation 'androidx.appcompat:appcompat:1.5.1'
-
- // Issue #488
- implementation 'com.unity3d.ads:unity-ads:4.4.0'
- implementation 'com.google.android.gms:play-services-ads:21.2.0'
- implementation platform('com.google.firebase:firebase-bom:30.5.0')
- implementation 'com.google.firebase:firebase-perf'
- implementation 'com.google.firebase:firebase-analytics'
- implementation 'com.google.firebase:firebase-crashlytics'
- implementation 'com.google.firebase:firebase-auth'
- implementation 'com.google.firebase:firebase-firestore'
- implementation 'com.google.android.gms:play-services-auth:20.3.0'
- implementation 'com.google.firebase:firebase-messaging'
- implementation 'com.google.firebase:firebase-database'
- implementation fileTree(dir: 'libs', include: ['*.aar'])
- implementation 'com.google.android.gms:play-services-appset:16.0.2'
- implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
- implementation 'com.google.android.gms:play-services-basement:18.1.0'
- implementation 'com.google.firebase:firebase-inappmessaging-display'
- implementation 'com.google.android.material:material:1.8.0-alpha01'
-
- implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
- implementation project (path: ':another-android-library')
-
- implementation platform('com.google.firebase:firebase-bom:30.5.0')
-
- implementation 'unresolved:unresolved:unresolved'
-}
-
diff --git a/xml-inflater/build.gradle.kts b/xml-inflater/build.gradle.kts
index e54325dc6..853a002a6 100644
--- a/xml-inflater/build.gradle.kts
+++ b/xml-inflater/build.gradle.kts
@@ -41,9 +41,5 @@ dependencies {
implementation(projects.resources)
testImplementation(projects.subprojects.projects)
- testImplementation(projects.subprojects.toolingApiTesting)
- testImplementation(projects.shared)
- testImplementation(libs.tests.junit)
- testImplementation(libs.tests.google.truth)
- testImplementation(libs.tests.robolectric)
+ testImplementation(projects.testing.tooling)
}