summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/checks/src/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosDetector.kt79
-rw-r--r--packages/SystemUI/checks/src/com/android/internal/systemui/lint/RunTestShouldUseKosmosDetector.kt6
-rw-r--r--packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosTest.kt104
3 files changed, 184 insertions, 5 deletions
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosDetector.kt
new file mode 100644
index 000000000000..40fac0d05b96
--- /dev/null
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosDetector.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.getContainingUClass
+
+/**
+ * Detects direct construction of `Kosmos()` in subclasses of SysuiTestCase, which can and should
+ * use `testKosmos`. See go/thetiger
+ */
+class DoNotDirectlyConstructKosmosDetector : Detector(), SourceCodeScanner {
+ override fun getApplicableConstructorTypes() = listOf("com.android.systemui.kosmos.Kosmos")
+
+ override fun visitConstructor(
+ context: JavaContext,
+ node: UCallExpression,
+ constructor: PsiMethod,
+ ) {
+ val superClassNames =
+ node.getContainingUClass()?.superTypes.orEmpty().map { it.resolve()?.qualifiedName }
+ if (superClassNames.contains("com.android.systemui.SysuiTestCase")) {
+ context.report(
+ issue = ISSUE,
+ scope = node,
+ location = context.getLocation(node.methodIdentifier),
+ message = "Prefer testKosmos to direct Kosmos() in sysui tests. go/testkosmos",
+ )
+ }
+ super.visitConstructor(context, node, constructor)
+ }
+
+ companion object {
+ @JvmStatic
+ val ISSUE =
+ Issue.create(
+ id = "DoNotDirectlyConstructKosmos",
+ briefDescription =
+ "Prefer testKosmos to direct Kosmos() in sysui tests. go/testkosmos",
+ explanation =
+ """
+ SysuiTestCase.testKosmos allows us to pre-populate a Kosmos instance with
+ team-standard fixture values, and makes it easier to make centralized changes
+ when necessary. See go/testkosmos
+ """,
+ category = Category.TESTING,
+ priority = 8,
+ severity = Severity.WARNING,
+ implementation =
+ Implementation(
+ DoNotDirectlyConstructKosmosDetector::class.java,
+ Scope.JAVA_FILE_SCOPE,
+ ),
+ )
+ }
+}
diff --git a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RunTestShouldUseKosmosDetector.kt b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RunTestShouldUseKosmosDetector.kt
index 4927fb9dc67d..13ffa6c5deaa 100644
--- a/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RunTestShouldUseKosmosDetector.kt
+++ b/packages/SystemUI/checks/src/com/android/internal/systemui/lint/RunTestShouldUseKosmosDetector.kt
@@ -29,16 +29,12 @@ import com.intellij.psi.PsiMethod
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.getContainingUFile
-/**
- * Detects test function naming violations regarding use of the backtick-wrapped space-allowed
- * feature of Kotlin functions.
- */
+/** Detects use of `TestScope.runTest` when we should use `Kosmos.runTest` by go/kosmos-runtest */
class RunTestShouldUseKosmosDetector : Detector(), SourceCodeScanner {
override fun getApplicableMethodNames() = listOf("runTest")
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
if (method.getReceiver()?.qualifiedName == "kotlinx.coroutines.test.TestScope") {
-
val imports =
node.getContainingUFile()?.imports.orEmpty().mapNotNull {
it.importReference?.asSourceString()
diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosTest.kt
new file mode 100644
index 000000000000..20f6bcbdbbfe
--- /dev/null
+++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/DoNotDirectlyConstructKosmosTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.internal.systemui.lint
+
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestFiles
+import com.android.tools.lint.checks.infrastructure.TestLintResult
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+class DoNotDirectlyConstructKosmosTest : SystemUILintDetectorTest() {
+ override fun getDetector(): Detector = DoNotDirectlyConstructKosmosDetector()
+
+ override fun getIssues(): List<Issue> = listOf(DoNotDirectlyConstructKosmosDetector.ISSUE)
+
+ @Test
+ fun wronglyTriesToDirectlyConstructKosmos() {
+ val runOnSource =
+ runOnSource(
+ """
+ package test.pkg.name
+
+ import com.android.systemui.kosmos.Kosmos
+ import com.android.systemui.SysuiTestCase
+
+ class MyTest: SysuiTestCase {
+ val kosmos = Kosmos()
+ }
+ """
+ )
+
+ runOnSource
+ .expectWarningCount(1)
+ .expect(
+ """
+ src/test/pkg/name/MyTest.kt:7: Warning: Prefer testKosmos to direct Kosmos() in sysui tests. go/testkosmos [DoNotDirectlyConstructKosmos]
+ val kosmos = Kosmos()
+ ~~~~~~
+ 0 errors, 1 warnings
+ """
+ )
+ }
+
+ @Test
+ fun okToConstructKosmosIfNotInSysuiTestCase() {
+ val runOnSource =
+ runOnSource(
+ """
+ package test.pkg.name
+
+ import com.android.systemui.kosmos.Kosmos
+
+ class MyTest {
+ val kosmos = Kosmos()
+ }
+ """
+ )
+
+ runOnSource.expectWarningCount(0)
+ }
+
+ private fun runOnSource(source: String): TestLintResult {
+ return lint()
+ .files(TestFiles.kotlin(source).indented(), kosmosStub, sysuiTestCaseStub)
+ .issues(DoNotDirectlyConstructKosmosDetector.ISSUE)
+ .run()
+ }
+
+ companion object {
+ private val kosmosStub: TestFile =
+ kotlin(
+ """
+ package com.android.systemui.kosmos
+
+ class Kosmos
+ """
+ )
+
+ private val sysuiTestCaseStub: TestFile =
+ kotlin(
+ """
+ package com.android.systemui
+
+ class SysuiTestCase
+ """
+ )
+ }
+}