Spaces:
Running
Running
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import app | |
| def _assert(cond: bool, msg: str) -> None: | |
| if not cond: | |
| raise AssertionError(msg) | |
| def test_prompt_uses_visible_rows_only() -> None: | |
| # If selected state contains stale hidden tags, prompt should still reflect visible-row selections only. | |
| row_defs = [ | |
| {"name": "r1", "label": "R1", "tags": ["solo", "female"], "tag_meta": {}}, | |
| {"name": "r2", "label": "R2", "tags": ["cub"], "tag_meta": {}}, | |
| ] | |
| payload = app._build_ui_payload( | |
| console_text="x", | |
| row_defs=row_defs, | |
| selected_tags=["solo", "rosalina_(mario)"], | |
| ) | |
| prompt_text = payload[2] | |
| selected_state = payload[3] | |
| _assert("rosalina \\(mario\\)" not in prompt_text, "stale hidden tag leaked into prompt") | |
| _assert("solo" in prompt_text, "visible selected tag missing from prompt") | |
| _assert("rosalina_(mario)" not in selected_state, "stale hidden tag leaked into selected state") | |
| def test_row_deduping() -> None: | |
| row_defs = [ | |
| { | |
| "name": "other_retrieved", | |
| "label": "Other (Retrieved)", | |
| "tags": ["cub", "expressions", "invalid_tag", "cub", "expressions"], | |
| "tag_meta": {}, | |
| } | |
| ] | |
| prompt_text, row_values_state, _, checkbox_updates = app._build_row_component_updates( | |
| row_defs=row_defs, | |
| selected_tags=["cub", "expressions"], | |
| max_rows=app.display_max_rows_default, | |
| ) | |
| _assert(prompt_text == "cub, expressions", "prompt should be deduped and ordered from row") | |
| _assert(row_values_state[0] == ["cub", "expressions"], "row selected values should be deduped") | |
| first_choices = checkbox_updates[0]["choices"] | |
| first_values = [v for _, v in first_choices] | |
| _assert(first_values == ["cub", "expressions", "invalid_tag"], "row choices should be deduped") | |
| def test_rebuild_ignores_stale_selected_state() -> None: | |
| row_defs = [ | |
| {"name": "selected_other", "label": "Selected (Other)", "tags": ["solo", "female", "anthro"], "tag_meta": {}}, | |
| {"name": "other_retrieved", "label": "Other (Retrieved)", "tags": ["cub", "expressions"], "tag_meta": {}}, | |
| ] | |
| # Simulate UI state where user has deselected anthro, but stale selected state still contains it. | |
| selected_state = ["solo", "female", "anthro", "cub"] | |
| row_values_state = [["solo", "female"], ["cub"]] | |
| out = app._rebuild_rows_from_selected( | |
| selected_state, | |
| row_defs, | |
| row_values_state, | |
| app.display_top_groups_default, | |
| app.display_top_tags_per_group_default, | |
| app.display_rank_top_k_default, | |
| ) | |
| prompt = out[1] | |
| selected_after = out[2] | |
| _assert("anthro" not in selected_after, "rebuild should not resurrect stale deselected tags") | |
| _assert("anthro" not in prompt, "prompt should not include stale deselected tags") | |
| _assert("solo" in prompt and "female" in prompt and "cub" in prompt, "rebuild should retain current row selections") | |
| def test_toggle_then_rebuild_does_not_resurrect_removed_tag() -> None: | |
| row_defs = [ | |
| {"name": "selected_other", "label": "Selected (Other)", "tags": ["solo", "anthro", "female"], "tag_meta": {}}, | |
| {"name": "other_retrieved", "label": "Other (Retrieved)", "tags": ["cub", "expressions"], "tag_meta": {}}, | |
| ] | |
| selected_state = ["solo", "anthro", "female", "cub"] | |
| row_values_state = [["solo", "anthro", "female"], ["cub"]] | |
| # User unchecks anthro in row 0. | |
| toggle_out = app._on_toggle_row( | |
| 0, | |
| ["solo", "female"], | |
| selected_state, | |
| False, | |
| row_defs, | |
| row_values_state, | |
| app.display_max_rows_default, | |
| ) | |
| selected_after_toggle = toggle_out[0] | |
| row_values_after_toggle = toggle_out[3] | |
| _assert("anthro" not in selected_after_toggle, "toggle should remove anthro from selected state") | |
| # Rebuild from current row values must preserve the user-toggle result. | |
| rebuild_out = app._rebuild_rows_from_selected( | |
| selected_after_toggle, | |
| row_defs, | |
| row_values_after_toggle, | |
| app.display_top_groups_default, | |
| app.display_top_tags_per_group_default, | |
| app.display_rank_top_k_default, | |
| ) | |
| prompt_after_rebuild = rebuild_out[1] | |
| selected_after_rebuild = rebuild_out[2] | |
| _assert("anthro" not in selected_after_rebuild, "rebuild should not resurrect deselected anthro") | |
| _assert("anthro" not in prompt_after_rebuild, "prompt should not contain deselected anthro after rebuild") | |
| _assert("solo" in prompt_after_rebuild and "female" in prompt_after_rebuild, "kept selections should remain") | |
| _assert("cub" in prompt_after_rebuild, "other retrieved selection should remain") | |
| def test_toggle_does_not_cross_activate_unrelated_row_tag() -> None: | |
| row_defs = [ | |
| {"name": "organization", "label": "Organization", "tags": ["pinup", "close-up"], "tag_meta": {}}, | |
| {"name": "color_markings", "label": "Color Markings", "tags": ["shoulder_markings", "black_markings"], "tag_meta": {}}, | |
| ] | |
| selected_state = [] | |
| row_values_state = [[], []] | |
| # User enables close-up in organization row. | |
| out = app._on_toggle_row( | |
| 0, | |
| ["close-up"], | |
| selected_state, | |
| False, | |
| row_defs, | |
| row_values_state, | |
| app.display_max_rows_default, | |
| ) | |
| selected_after = out[0] | |
| row_values_after = out[3] | |
| _assert("close-up" in selected_after, "close-up should be selected") | |
| _assert("shoulder_markings" not in selected_after, "unrelated row tag should not be auto-selected") | |
| _assert(row_values_after[0] == ["close-up"], "organization row values should include close-up only") | |
| _assert(row_values_after[1] == [], "color markings row should remain unselected") | |
| def test_shared_tag_mirrors_without_unrelated_cross_toggle() -> None: | |
| row_defs = [ | |
| {"name": "objects_props", "label": "Objects Props", "tags": ["holding_face", "holding_clothing"], "tag_meta": {}}, | |
| {"name": "expression_detail", "label": "Expression Detail", "tags": ["open_mouth", "closed_smile"], "tag_meta": {}}, | |
| {"name": "pose_action_detail", "label": "Pose Action Detail", "tags": ["holding_face", "walking"], "tag_meta": {}}, | |
| ] | |
| selected_state = [] | |
| row_values_state = [[], [], []] | |
| # Enable open_mouth; should not affect holding_face rows. | |
| out1 = app._on_toggle_row( | |
| 1, | |
| ["open_mouth"], | |
| selected_state, | |
| False, | |
| row_defs, | |
| row_values_state, | |
| app.display_max_rows_default, | |
| ) | |
| sel1 = out1[0] | |
| vals1 = out1[3] | |
| _assert("open_mouth" in sel1, "open_mouth should be selected") | |
| _assert("holding_face" not in sel1, "holding_face must remain unselected") | |
| _assert(vals1[0] == [], "objects props row should remain unselected") | |
| _assert(vals1[1] == ["open_mouth"], "expression row should select open_mouth") | |
| _assert(vals1[2] == [], "pose row should remain unselected") | |
| # Enable holding_face in objects row; should mirror only to pose row, not expression row. | |
| out2 = app._on_toggle_row( | |
| 0, | |
| ["holding_face"], | |
| sel1, | |
| True, | |
| row_defs, | |
| vals1, | |
| app.display_max_rows_default, | |
| ) | |
| sel2 = out2[0] | |
| vals2 = out2[3] | |
| _assert("holding_face" in sel2 and "open_mouth" in sel2, "both explicitly selected tags should be present") | |
| _assert(vals2[0] == ["holding_face"], "objects row should select holding_face") | |
| _assert(vals2[1] == ["open_mouth"], "expression row should keep open_mouth only") | |
| _assert(vals2[2] == ["holding_face"], "pose row should mirror holding_face") | |
| def main() -> None: | |
| test_prompt_uses_visible_rows_only() | |
| test_row_deduping() | |
| test_rebuild_ignores_stale_selected_state() | |
| test_toggle_then_rebuild_does_not_resurrect_removed_tag() | |
| test_toggle_does_not_cross_activate_unrelated_row_tag() | |
| test_shared_tag_mirrors_without_unrelated_cross_toggle() | |
| print("ui state smoke: ok") | |
| if __name__ == "__main__": | |
| main() | |