File size: 3,621 Bytes
e2f048d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | """A change you cannot measure is a change you cannot verify."""
from tiny_computer_agent import ChangeVerifier, Delta, Element, Observation, diff, element_key
def frame(elements, text=""):
return Observation(index=0, frame="frame", elements=tuple(elements), text=text)
def button(label, x=10, y=10, width=60, height=20, kind="button"):
return Element(label, kind=kind, x=x, y=y, width=width, height=height)
def test_nothing_changed_is_measured_rather_than_guessed():
picture = frame([button("Save", x=100)])
delta = diff(picture, picture)
assert delta.empty and not delta.changed
assert delta.summary() == "no change"
assert isinstance(delta, Delta)
def test_a_dialog_closing_is_a_removed_element_not_a_missing_string():
"""The whole point: verification without depending on the dialog's own words."""
before = frame([button("Save As"), button("Cancel", x=80)])
after = frame([button("Save As")])
delta = diff(before, after)
assert delta.closed and not delta.opened
assert [e.label for e in delta.removed] == ["Cancel"]
assert delta.matches(disappeared=["cancel"])
assert not delta.matches(appeared=["cancel"])
def test_a_menu_opening_is_an_added_element():
delta = diff(frame([button("File")]), frame([button("File"), button("Save As", y=60)]))
assert delta.opened and not delta.closed
assert [e.label for e in delta.added] == ["Save As"]
assert delta.matches(appeared=["save as"])
def test_a_redraw_is_not_movement_and_a_real_move_is():
still = diff(frame([button("Save", x=100)]), frame([button("Save", x=101)]))
assert still.empty, "a one-pixel re-render is not a change"
moved = diff(frame([button("Save", x=100)]), frame([button("Save", x=400)]))
assert moved.moved and moved.settled, "nothing appeared or vanished: it moved"
assert not moved.changed is False
assert moved.to_dict()["moved"] == ["Save"]
def test_labels_are_compared_the_way_the_index_compares_them():
"""OCR drops spaces and models add punctuation, so identity is the alphanumeric core."""
before = frame([button("Save As")])
after = frame([button("SaveAs.")])
delta = diff(before, after)
assert delta.empty, "the same label, differently spelled, is the same element"
assert element_key(button("Save As")) == element_key(button("SaveAs."))
def test_added_and_removed_are_told_apart_when_counts_differ():
before = frame([button("Row 1"), button("Row 2")])
after = frame([button("Row 2"), button("Row 3"), button("Row 4")])
delta = diff(before, after)
assert sorted(e.label for e in delta.added) == ["Row 3", "Row 4"]
assert [e.label for e in delta.removed] == ["Row 1"]
assert delta.summary().startswith("+2")
def test_the_verifier_remembers_the_previous_frame():
verify = ChangeVerifier(disappeared=["Cancel"])
with_cancel = frame([button("Save"), button("Cancel", x=200)])
without_cancel = frame([button("Save")])
assert verify(with_cancel) is False, "the first frame has nothing to compare against"
assert verify(without_cancel) is True
assert verify.last is not None and verify.last.closed, "Cancel is gone: the dialog closed"
assert verify(without_cancel) is False, "and the comparison advances with the frame"
assert verify.last is not None and verify.last.empty
def test_the_verifier_can_be_reset_between_episodes():
verify = ChangeVerifier(appeared=["Saved"])
verify(frame([button("Save")]))
verify.reset()
assert verify.previous is None and verify.last is None
assert verify(frame([button("Saved")])) is False
|