diff --git a/scripts/src/java/org/oppia/android/scripts/xml/TextViewStyleCheck.kt b/scripts/src/java/org/oppia/android/scripts/xml/TextViewStyleCheck.kt index 1416c6498d6..45b6d86a2b9 100644 --- a/scripts/src/java/org/oppia/android/scripts/xml/TextViewStyleCheck.kt +++ b/scripts/src/java/org/oppia/android/scripts/xml/TextViewStyleCheck.kt @@ -36,6 +36,7 @@ private class TextViewStyleCheck { private val directionalityWarnings = mutableListOf() private val LINE_NUMBER_ATTRIBUTE = "lineNumber" + /** Checks XML files for TextView elements to ensure compliance with style requirements. */ fun checkFiles(xmlFiles: List) { xmlFiles.forEach { file -> processXmlFile(file) } printResults() @@ -55,6 +56,9 @@ private class TextViewStyleCheck { private fun validateTextViewElement(element: Element, filePath: String) { val lineNumber = element.getAttribute(LINE_NUMBER_ATTRIBUTE).toInt().minus(1).toString() val styleAttribute = element.attributes.getNamedItem("style")?.nodeValue + val idAttribute = element.attributes.getNamedItem("android:id")?.nodeValue ?: "NO ID" + + if (idAttribute in attributeIds) return if (styleAttribute.isNullOrBlank()) { styleValidationIssues.add( @@ -81,14 +85,11 @@ private class TextViewStyleCheck { "android:layout_toRightOf" ) - for (legacyAttr in legacyAttributes) { - if (element.hasAttribute(legacyAttr)) { - directionalityWarnings.add( - "WARNING: Hardcoded left/right attribute in file: $filePath, line $lineNumber. " + - "Consider using start/end." - ) - break - } + if (legacyAttributes.any { element.hasAttribute(it) }) { + directionalityWarnings.add( + "WARNING: Hardcoded left/right attribute in file: $filePath, line $lineNumber. " + + "Consider using start/end." + ) } } @@ -170,3 +171,107 @@ private class TextViewStyleCheck { return doc } } + +// Known exceptions that currently lack a style and are being tracked for fixes. +private val attributeIds = listOf( + "@+id/developer_options_text_view", + "@+id/onboarding_language_text_view", + "@+id/walkthrough_final_no_text_view", + "@+id/walkthrough_final_yes_text_view", + "@+id/walkthrough_final_title_text_view", + "@+id/chapter_index", + "@+id/chapter_index", + "@+id/test_text_view", + "@+id/feedback_text_view", + "@+id/item_selection_contents_text_view", + "@+id/learner_analytics_sync_status_text_view", + "@+id/text_view_for_int_no_data_binding", + "@+id/walkthrough_topic_name_text_view", + "@+id/walkthrough_lesson_count_text_view", + "@+id/hint_bar_title", + "@+id/coming_soon_text_view", + "@+id/topic_name_text_view", + "@+id/lesson_count_text_view", + "@+id/multiple_choice_content_text_view", + "@+id/language_text_view", + "@+id/welcome_text_view", + "@+id/app_version_text_view", + "@+id/app_last_update_date_text_view", + "@+id/test_margin_text_view", + "@+id/content_text_view", + "@+id/action_options", + "@+id/action_help", + "@+id/action_close", + "@+id/continue_studying_text_view", + "@+id/language_unavailable_notice", + "@+id/story_progress_chapter_completed_text", + "@+id/profile_id_view_profile_name", + "@+id/profile_id_view_learner_id", + "@+id/learner_events_waiting_upload_label", + "@+id/learner_events_waiting_upload_count", + "@+id/learner_events_uploaded_label", + "@+id/learner_events_uploaded_count", + "@+id/uncategorized_events_waiting_upload_label", + "@+id/uncategorized_events_waiting_upload_count", + "@+id/uncategorized_events_uploaded_label", + "@+id/uncategorized_events_uploaded_count", + "@+id/text_view_for_live_data_no_data_binding", + "@+id/selection_interaction_textview", + "@+id/onboarding_steps_count", + "@+id/profile_picture_edit_dialog_view_picture", + "@+id/profile_picture_edit_dialog_change_picture", + "@+id/chapter_title", + "@+id/walkthrough_welcome_title_text_view", + "@+id/story_name_text_view", + "@+id/topic_name_text_view", + "@+id/chapter_index", + "@+id/copyright_license_text_view", + "@+id/multiple_choice_content_text_view", + "@+id/ga_update_notice_dialog_message", + "@+id/create_profile_picture_prompt", + "@+id/profile_reset_pin_main", + "@+id/submitted_answer_text_view", + "@+id/language_text_view", + "@+id/end_session_header_text_view", + "@+id/end_session_body_text_view", + "@+id/question_progress_text", + "@+id/congratulations_text_view", + "@+id/beta_notice_dialog_message", + "@+id/chapter_index", + "@+id/onboarding_language_explanation", + "@+id/onboarding_steps_count", + "@+id/create_profile_picture_prompt", + "@+id/create_profile_title", + "@+id/end_session_header_text_view", + "@+id/end_session_body_text_view", + "@+id/question_progress_text", + "@+id/congratulations_text_view", + "@+id/walkthrough_final_no_text_view", + "@+id/walkthrough_final_yes_text_view", + "@+id/walkthrough_final_title_text_view", + "@+id/profile_name_text_view", + "@+id/create_profile_picture_prompt", + "@+id/create_profile_title", + "@+id/end_session_header_text_view", + "@+id/end_session_body_text_view", + "@+id/question_progress_text", + "@+id/congratulations_text_view", + "@+id/resume_lesson_chapter_title_text_view", + "@+id/topic_name_text_view", + "@+id/story_count_text_view", + "@+id/download_size_text_view", + "@+id/onboarding_language_explanation", + "@+id/onboarding_steps_count", + "@+id/create_profile_picture_prompt", + "@+id/create_profile_title", + "@+id/end_session_header_text_view", + "@+id/end_session_body_text_view", + "@+id/question_progress_text", + "@+id/options_activity_selected_options_title", + "@+id/profile_select_text", + "@+id/continue_studying_text_view", + "@+id/extra_controls_title", + "@+id/chapter_title", + "@+id/options_activity_selected_options_title", + "@+id/view_all_text_view" +) diff --git a/scripts/src/javatests/org/oppia/android/scripts/xml/TextViewStyleCheckTest.kt b/scripts/src/javatests/org/oppia/android/scripts/xml/TextViewStyleCheckTest.kt index 69e8b03b55e..899fc987f52 100644 --- a/scripts/src/javatests/org/oppia/android/scripts/xml/TextViewStyleCheckTest.kt +++ b/scripts/src/javatests/org/oppia/android/scripts/xml/TextViewStyleCheckTest.kt @@ -266,8 +266,8 @@ class TextViewStyleCheckTest { val output = outContent.toString() assertThat(thrown).isInstanceOf(Exception::class.java) - assertThat(output).contains("line 8") // First TextView error - assertThat(output).contains("line 17") // Second TextView warning + assertThat(output).contains("line 8") + assertThat(output).contains("line 17") } @Test fun testTextViewStyle_nestedTextViews_logsCorrectLineNumbers() { @@ -302,8 +302,8 @@ class TextViewStyleCheckTest { val output = outContent.toString() assertThat(thrown).isInstanceOf(Exception::class.java) - assertThat(output).contains("line 11") // First TextView error - assertThat(output).contains("line 19") // Second TextView warning + assertThat(output).contains("line 11") + assertThat(output).contains("line 19") } private fun createLayoutFile(content: String, fileName: String = "test_layout.xml") {