in designer/testSrc/com/android/tools/idea/uibuilder/visual/visuallint/VisualLintAnalysisTest.kt [87:309]
fun visualLintAnalysis() {
projectRule.load("projects/visualLintApplication")
val module = projectRule.getModule("app")
val activityLayout =
projectRule.project.baseDir.findFileByRelativePath(
"app/src/main/res/layout/activity_main.xml"
)!!
val dashboardLayout =
projectRule.project.baseDir.findFileByRelativePath(
"app/src/main/res/layout/fragment_dashboard.xml"
)!!
val notificationsLayout =
projectRule.project.baseDir.findFileByRelativePath(
"app/src/main/res/layout/fragment_notifications.xml"
)!!
val homeLayout =
projectRule.project.baseDir.findFileByRelativePath(
"app/src/main/res/layout/fragment_home.xml"
)!!
var filesToAnalyze = listOf(activityLayout, dashboardLayout, notificationsLayout, homeLayout)
analyzeFile(module, filesToAnalyze, "_device_class_phone")
analyzeFile(module, filesToAnalyze, "_device_class_foldable")
analyzeFile(module, filesToAnalyze, "_device_class_tablet")
analyzeFile(module, filesToAnalyze, "_device_class_desktop")
val issues = issueProvider.getIssues()
assertEquals(6, issues.size)
issues.forEach {
assertEquals("Visual Lint Issue", it.category)
when ((it as VisualLintRenderIssue).type) {
VisualLintErrorType.OVERLAP -> {
assertEquals(3, it.models.size)
assertEquals("text_dashboard <TextView> is covered by imageView <ImageView>", it.summary)
assertEquals(
"Content of text_dashboard <TextView> is partially covered by imageView <ImageView> in 3 preview configurations." +
"<BR/>This may affect text readability. Fix this issue by adjusting widget positioning.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
VisualLintErrorType.BOTTOM_NAV -> {
assertEquals(3, it.models.size)
assertEquals(
"Bottom navigation bar is not recommended for breakpoints over 600dp",
it.summary,
)
assertEquals(
"Bottom navigation bar is not recommended for breakpoints >= 600dp, which affects 3 preview configurations." +
"<BR/>Material Design recommends replacing bottom navigation bar with " +
"<A HREF=\"https://d.android.com/r/studio-ui/designer/material/navigation-rail\">navigation rail</A> or " +
"<A HREF=\"https://d.android.com/r/studio-ui/designer/material/navigation-drawer\">navigation drawer</A> " +
"for breakpoints >= 600dp.",
it.description,
)
assertNotNull(it.hyperlinkListener)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
VisualLintErrorType.LONG_TEXT -> {
assertEquals(2, it.models.size)
assertEquals(
"text_notifications <TextView> has lines containing more than 120 characters",
it.summary,
)
assertEquals(
"TextView has lines containing more than 120 characters in 2 preview configurations.<BR/>Material Design recommends " +
"reducing the width of TextView or switching to a " +
"<A HREF=\"https://m3.material.io/foundations/layout/applying-layout/window-size-classes#a9594611-a6d4-4dce-abcb-15e7dd431f8a\">" +
"multi-column layout</A> for breakpoints >= 600dp.",
it.description,
)
assertNotNull(it.hyperlinkListener)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
VisualLintErrorType.BOUNDS -> {
assertEquals(2, it.models.size)
assertEquals("imageView <ImageView> is partially hidden in layout", it.summary)
assertEquals(
"ImageView is partially hidden in layout because it is not contained within the bounds of its parent in 2 preview " +
"configurations.<BR/>Fix this issue by adjusting the size or position of ImageView.",
it.description,
)
assertEquals(HighlightSeverity.ERROR, it.severity)
}
VisualLintErrorType.BUTTON_SIZE -> {
assertEquals(4, it.models.size)
assertEquals("The button button <Button> is too wide", it.summary)
assertEquals(
"The button Button is wider than 320dp in 4 preview configurations." +
"<BR/>Material Design recommends buttons to be no wider than 320dp",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
VisualLintErrorType.TEXT_FIELD_SIZE -> {
assertEquals(3, it.models.size)
assertEquals("The text field text_field <EditText> is too wide", it.summary)
assertEquals(
"The text field EditText is wider than 488dp in 3 preview configurations." +
"<BR/>Material Design recommends text fields to be no wider than 488dp",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
else -> fail("Unexpected visual lint error")
}
assertEquals(it.components.size, it.source.components.size)
assertEquals(it.models.size, it.source.models.size)
}
projectRule.fixture.disableInspections(
BoundsAnalyzerInspection(),
TextFieldSizeAnalyzerInspection(),
)
issueProvider.clear()
analyzeFile(module, filesToAnalyze, "_device_class_phone")
analyzeFile(module, filesToAnalyze, "_device_class_foldable")
analyzeFile(module, filesToAnalyze, "_device_class_tablet")
analyzeFile(module, filesToAnalyze, "_device_class_desktop")
assertEquals(4, issues.size)
issues
.map { it as VisualLintRenderIssue }
.forEach {
assertNotEquals(VisualLintErrorType.BOUNDS, it.type)
assertNotEquals(VisualLintErrorType.TEXT_FIELD_SIZE, it.type)
}
val wearLayout =
projectRule.project.baseDir.findFileByRelativePath(
"app/src/main/res/layout/wear_layout.xml"
)!!
filesToAnalyze = listOf(wearLayout)
issueProvider.clear()
analyzeFile(module, filesToAnalyze, "_device_class_phone")
assertEquals(7, issues.size)
issues
.map { it as VisualLintRenderIssue }
.forEach { assertNotEquals(VisualLintErrorType.WEAR_MARGIN, it.type) }
issueProvider.clear()
analyzeFile(module, filesToAnalyze, "wearos_square")
analyzeFile(module, filesToAnalyze, "wearos_rect")
analyzeFile(module, filesToAnalyze, "wearos_small_round")
analyzeFile(module, filesToAnalyze, "wearos_large_round")
assertEquals(12, issues.size)
val wearIssues =
issues.filterIsInstance<VisualLintRenderIssue>().filter {
it.type == VisualLintErrorType.WEAR_MARGIN
}
assertEquals(5, wearIssues.size)
wearIssues.forEach {
assertEquals("Visual Lint Issue", it.category)
when (it.components.first().id) {
"image_view" -> {
assertEquals(3, it.models.size)
assertEquals(
"The view image_view <ImageView> is too close to the side of the device",
it.summary,
)
assertEquals(
"In 3 preview configurations, the view ImageView is closer to the side of the device than the recommended amount.<BR/>" +
"It is recommended that, for Wear OS layouts, margins should be at least 2.5% for square devices, and 5.2% for round devices.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
"textview1" -> {
assertEquals(4, it.models.size)
assertEquals(
"The view textview1 <TextView> is too close to the side of the device",
it.summary,
)
assertEquals(
"In 4 preview configurations, the view TextView is closer to the side of the device than the recommended amount.<BR/>" +
"It is recommended that, for Wear OS layouts, margins should be at least 2.5% for square devices, and 5.2% for round devices.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
"textview2" -> {
assertEquals(1, it.models.size)
assertEquals(
"The view textview2 <TextView> is too close to the side of the device",
it.summary,
)
assertEquals(
"In a preview configuration, the view TextView is closer to the side of the device than the recommended amount.<BR/>" +
"It is recommended that, for Wear OS layouts, margins should be at least 2.5% for square devices, and 5.2% for round devices.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
"textview3" -> {
assertEquals(3, it.models.size)
assertEquals(
"The view textview3 <TextView> is too close to the side of the device",
it.summary,
)
assertEquals(
"In 3 preview configurations, the view TextView is closer to the side of the device than the recommended amount.<BR/>" +
"It is recommended that, for Wear OS layouts, margins should be at least 2.5% for square devices, and 5.2% for round devices.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
"textview4" -> {
assertEquals(1, it.models.size)
assertEquals(
"The view textview4 <TextView> is too close to the side of the device",
it.summary,
)
assertEquals(
"In a preview configuration, the view TextView is closer to the side of the device than the recommended amount.<BR/>" +
"It is recommended that, for Wear OS layouts, margins should be at least 2.5% for square devices, and 5.2% for round devices.",
it.description,
)
assertEquals(HighlightSeverity.WARNING, it.severity)
}
}
}
}