Prompt_Squirrel_RAG / scripts /smoke_ui_state.py
Food Desert
Finalize classifier-assisted tagging updates
dfedb9d
Raw
History Blame Contribute Delete
13.8 kB
import sys
import re
import json
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 _css_block(selector: str) -> str:
pat = re.compile(rf"{re.escape(selector)}\s*\{{([^}}]+)\}}", re.DOTALL)
m = pat.search(app.css)
_assert(m is not None, f"missing CSS selector block: {selector}")
return m.group(1)
def _css_prop(block: str, prop: str) -> str:
pat = re.compile(rf"{re.escape(prop)}\s*:\s*([^;]+);", re.IGNORECASE)
m = pat.search(block)
_assert(m is not None, f"missing CSS property '{prop}' in block: {block}")
return m.group(1).strip().lower()
def test_toggle_color_contract_matches_legend() -> None:
legend_bg_by_origin = {
"rewrite": _css_prop(_css_block(".source-legend .chip.rewrite"), "background"),
"selection": _css_prop(_css_block(".source-legend .chip.selection"), "background"),
"structural": _css_prop(_css_block(".source-legend .chip.structural"), "background"),
"classifier": _css_prop(_css_block(".source-legend .chip.classifier"), "background"),
"implied": _css_prop(_css_block(".source-legend .chip.implied"), "background"),
"user": _css_prop(_css_block(".source-legend .chip.user"), "background"),
}
on_bg2_by_origin = {
"rewrite": _css_prop(_css_block('.lego-tags label[data-psq-preselected="1"][data-psq-origin="rewrite"] span'), "--on-bg2"),
"selection": _css_prop(_css_block('.lego-tags label[data-psq-preselected="1"][data-psq-origin="selection"] span'), "--on-bg2"),
"structural": _css_prop(_css_block('.lego-tags label[data-psq-preselected="1"][data-psq-origin="structural"] span'), "--on-bg2"),
"classifier": _css_prop(_css_block('.lego-tags label[data-psq-preselected="1"][data-psq-origin="classifier"] span'), "--on-bg2"),
"implied": _css_prop(_css_block('.lego-tags label[data-psq-preselected="1"][data-psq-origin="implied"] span'), "--on-bg2"),
"user": _css_prop(_css_block('.lego-tags label[data-psq-preselected="0"] span'), "--on-bg2"),
}
for origin, legend_bg in legend_bg_by_origin.items():
_assert(
on_bg2_by_origin[origin] == legend_bg,
f"legend/toggle color mismatch for '{origin}': toggle={on_bg2_by_origin[origin]} legend={legend_bg}",
)
def test_client_js_stamps_source_color_attributes() -> None:
js = app.client_js
has_origin_attr = ("data-psq-origin" in js) or ("dataset.psqOrigin" in js)
has_preselected_attr = ("data-psq-preselected" in js) or ("dataset.psqPreselected" in js)
_assert(has_origin_attr, "client_js does not stamp per-tag origin attributes on checkbox labels")
_assert(has_preselected_attr, "client_js does not stamp per-tag preselected attributes on checkbox labels")
def test_tooltip_payload_includes_row_meta_for_color_mapping() -> None:
row_defs = [
{
"name": "r1",
"label": "R1",
"tags": ["solo", "female"],
"tag_meta": {
"solo": {"origin": "rewrite", "preselected": True},
"female": {"origin": "selection", "preselected": False},
},
}
]
raw = app._build_tooltip_payload(row_defs, max_rows=app.display_max_rows_default)
payload = json.loads(raw)
_assert("meta_rows" in payload, "tooltip payload missing meta_rows")
_assert(isinstance(payload["meta_rows"], list), "tooltip payload meta_rows must be a list")
_assert(len(payload["meta_rows"]) == 1, "meta_rows should align with visible row count")
_assert(isinstance(payload["meta_rows"][0], list), "meta_rows row must be a list")
_assert(len(payload["meta_rows"][0]) == 2, "meta_rows tag metadata count must align with tags")
first = payload["meta_rows"][0][0]
second = payload["meta_rows"][0][1]
_assert(first.get("origin") == "rewrite", "first tag origin metadata mismatch")
_assert(first.get("preselected") is True, "first tag preselected metadata mismatch")
_assert(second.get("origin") == "selection", "second tag origin metadata mismatch")
_assert(second.get("preselected") is False, "second tag preselected metadata mismatch")
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[4]["value"]
selected_state = payload[5]
_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_rebuild_preserves_user_toggled_provenance() -> None:
row_defs = [
{
"name": "demo_row",
"label": "Demo Row",
"tags": ["base_tag", "manual_tag"],
"tag_meta": {
"base_tag": {"origin": "selection", "preselected": True},
"manual_tag": {"origin": "selection", "preselected": False},
},
}
]
selected_state = ["base_tag", "manual_tag"]
row_values_state = [["base_tag", "manual_tag"]]
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,
)
rebuilt_rows = out[6]
manual_meta = None
for row in rebuilt_rows:
tags = row.get("tags", []) if isinstance(row, dict) else []
if "manual_tag" in tags:
row_meta = row.get("tag_meta", {}) if isinstance(row.get("tag_meta", {}), dict) else {}
manual_meta = row_meta.get("manual_tag")
if manual_meta:
break
_assert(manual_meta is not None, "manual_tag metadata missing after rebuild")
_assert(manual_meta.get("origin") == "user", "rebuild should preserve manual_tag origin as user")
_assert(manual_meta.get("preselected") is False, "rebuild should preserve manual_tag preselected=False")
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_toggle_color_contract_matches_legend()
test_client_js_stamps_source_color_attributes()
test_tooltip_payload_includes_row_meta_for_color_mapping()
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_rebuild_preserves_user_toggled_provenance()
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()