From ab5daacdbefe86337b6a3a3bf91f3d4d6df41ff8 Mon Sep 17 00:00:00 2001 From: Quinten Steenhuis Date: Tue, 7 Jul 2026 13:11:01 -0400 Subject: [PATCH 1/2] Suppress WA515 for conditional duplicate labels --- src/dayamlchecker/accessibility.py | 31 ++++++++++++-- tests/test_yaml_structure.py | 66 ++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/dayamlchecker/accessibility.py b/src/dayamlchecker/accessibility.py index dcbd400..9ccbdca 100644 --- a/src/dayamlchecker/accessibility.py +++ b/src/dayamlchecker/accessibility.py @@ -38,6 +38,12 @@ "field", "__line__", } +FIELD_VISIBILITY_KEYS = ( + "show if", + "hide if", + "js show if", + "js hide if", +) GENERIC_LINK_TEXT = { "click here", "here", @@ -522,7 +528,7 @@ def _check_choice_labels( def _check_duplicate_field_labels( doc: dict[str, Any], document_start_line: int ) -> list[FindingDraft]: - labels: dict[str, list[tuple[int, str]]] = {} + labels: dict[str, list[tuple[int, str, bool]]] = {} for field in _iter_fields(doc): if not _field_collects_user_input(field): continue @@ -534,18 +540,20 @@ def _check_duplicate_field_labels( ( _field_line_number(doc, field, document_start_line), label, + _field_has_visibility_logic(field), ) ) findings: list[FindingDraft] = [] for entries in labels.values(): - if len(entries) < 2: + always_visible_entries = [entry for entry in entries if not entry[2]] + if len(always_visible_entries) < 2: continue findings.append( draft( MessageId.ACCESSIBILITY_DUPLICATE_FIELD_LABEL, - line_number=entries[0][0], - labels=", ".join(label for _, label in entries[:3]), + line_number=always_visible_entries[0][0], + labels=", ".join(label for _, label, _ in always_visible_entries[:3]), ) ) return findings @@ -1280,6 +1288,21 @@ def _field_collects_user_input(field: dict[str, Any]) -> bool: return any(str(key).strip() not in FIELD_NON_LABEL_KEYS for key in field.keys()) +def _field_has_visibility_logic(field: dict[str, Any]) -> bool: + return any( + _has_nonempty_visibility_condition(field.get(key)) + for key in FIELD_VISIBILITY_KEYS + ) + + +def _has_nonempty_visibility_condition(value: Any) -> bool: + if value is None: + return False + if isinstance(value, str): + return bool(value.strip()) + if isinstance(value, (dict, list, tuple, set)): + return bool(value) + return True def _iter_choice_labels_with_lines( choice_value: Any, ) -> list[tuple[str, Optional[int]]]: diff --git a/tests/test_yaml_structure.py b/tests/test_yaml_structure.py index 67e0d6c..de4cf92 100644 --- a/tests/test_yaml_structure.py +++ b/tests/test_yaml_structure.py @@ -756,6 +756,72 @@ def test_accessibility_no_label_uses_variable_from_no_label_key(self): f"Expected no-label accessibility error to include variable name, got: {errs}", ) + def test_accessibility_duplicate_field_label_fails_for_always_visible_fields(self): + yaml_content = """question: | + Enter contact information +fields: + - Name: first_name + - Name: second_name +""" + errs = find_errors_from_string( + yaml_content, + input_file="", + lint_mode="accessibility", + ) + self.assertTrue( + any(e.code == "WA515" for e in errs), + f"Expected duplicate field label warning, got: {errs}", + ) + + def test_accessibility_duplicate_field_label_suppressed_for_conditional_other_context( + self, + ): + yaml_content = """question: | + What else should we know? +fields: + - Help types: help_types + datatype: checkboxes + choices: + - Housing + - Other + - Other: help_other + show if: help_types["Other"] + - Document types: document_types + datatype: checkboxes + choices: + - ID + - Other + - Other: document_other + show if: document_types["Other"] +""" + errs = find_errors_from_string( + yaml_content, + input_file="", + lint_mode="accessibility", + ) + self.assertFalse( + any(e.code == "WA515" for e in errs), + f"Did not expect duplicate field label warning for contextual Other fields, got: {errs}", + ) + + def test_accessibility_duplicate_field_label_suppressed_for_hidden_field(self): + yaml_content = """question: | + Enter mailing information +fields: + - Address: mailing_address + - Address: physical_address + hide if: use_mailing_address +""" + errs = find_errors_from_string( + yaml_content, + input_file="", + lint_mode="accessibility", + ) + self.assertFalse( + any(e.code == "WA515" for e in errs), + f"Did not expect duplicate field label warning for hidden duplicate, got: {errs}", + ) + def test_accessibility_tagged_pdf_info_for_docx_without_setting(self): yaml_content = """attachments: - name: Letter From a0c51c8cbd08d2eca90967d7e2c7c6ac05fbe85b Mon Sep 17 00:00:00 2001 From: Quinten Steenhuis Date: Tue, 7 Jul 2026 13:21:35 -0400 Subject: [PATCH 2/2] Formatting --- src/dayamlchecker/accessibility.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dayamlchecker/accessibility.py b/src/dayamlchecker/accessibility.py index 9ccbdca..12cee33 100644 --- a/src/dayamlchecker/accessibility.py +++ b/src/dayamlchecker/accessibility.py @@ -1303,6 +1303,8 @@ def _has_nonempty_visibility_condition(value: Any) -> bool: if isinstance(value, (dict, list, tuple, set)): return bool(value) return True + + def _iter_choice_labels_with_lines( choice_value: Any, ) -> list[tuple[str, Optional[int]]]: