"""The probe: what it draws, without a pad or a terminal.""" from dora_teleop import mapping, probe from dora_teleop.joy import Sample from tests.conftest import buttons_for, stick def test_a_centred_stick_puts_the_marker_in_the_middle(): drawn = probe.bar(0.0) assert drawn[len(drawn) // 2] == "#" def test_the_bar_leans_the_way_the_stick_is_pushed(): left = probe.bar(-1.0) right = probe.bar(1.0) assert left.index("#") < left.index("|") assert right.index("#") > right.index("|") def test_a_reading_beyond_full_deflection_stays_on_the_bar(): # SDL has been known to report slightly outside -1..1 on a worn stick. assert "#" in probe.bar(-4.0) assert "#" in probe.bar(4.0) def test_no_gamepad_says_so_and_says_the_arm_is_being_held_still(config): # Absence covers both "no pad" and "dora-joy stopped sending", and the probe # must not imply the arm is waiting on something it is not. drawn = probe.render(Sample(present=False), Sample(present=False), [0.0] * 6, config) assert "no gamepad" in drawn assert "hold still" in drawn def test_every_axis_the_pad_reports_is_shown_even_the_unused_ones(config): # A pad whose sticks land on indices we do not use is exactly what this is # for, so nothing may be hidden. sample = Sample(axes=[0.0] * 8, buttons=[], present=True) drawn = probe.render(sample, sample, [0.0] * 6, config) assert "unused" in drawn assert "axes (8 reported)" in drawn def test_a_pressed_button_is_named(config): sample = stick(buttons=buttons_for(grasp=True)) drawn = probe.render(sample, sample, [0.0] * 6, config) assert "grasp" in drawn def test_nothing_pressed_says_so_rather_than_showing_an_empty_line(config): drawn = probe.render(stick(), stick(), [0.0] * 6, config) assert "none pressed" in drawn def test_the_velocity_is_shown_in_the_units_the_arm_takes(config): pushed = stick(axes=[0.0, -1.0]) velocity = mapping.velocity(pushed.axes, [], config) drawn = probe.render(pushed, pushed, velocity, config) assert "mm/s" in drawn assert "deg/s" in drawn assert f"{config.speed_mm_s:+8.2f}" in drawn def test_a_still_arm_is_reported_as_still(config): drawn = probe.render(stick(), stick(), [0.0] * 6, config) assert "told to hold still" in drawn def test_a_moving_arm_is_reported_as_moving(config): pushed = stick(axes=[0.0, -1.0]) drawn = probe.render(pushed, pushed, [10.0, 0, 0, 0, 0, 0], config) assert "moving: yes" in drawn def test_whether_the_pad_is_asking_for_the_arm_is_shown(config): # The probe is where a resting trigger claiming the arm would have been # visible, so it says what `is_active` thinks rather than leaving it implied. rest, pushed = stick(), stick(axes=[0.0, -1.0]) assert "asking for the arm: no" in probe.render(rest, rest, [0.0] * 6, config) assert "asking for the arm: yes" in probe.render(pushed, pushed, [0.0] * 6, config) def test_a_pad_that_does_not_fit_the_layout_is_called_out(config): # This is the tool for exactly that pad, so the reason goes on the screen # rather than only in the node's log. wrong = stick(axes=[0.0, 0.0, 0.0, -1.0, -1.0, -1.0]) mismatch = "axis 3 rests at -1.000, which is not where right stick Y sits" drawn = probe.render(wrong, Sample(present=False), [0.0] * 6, config, mismatch) assert "does not match the layout" in drawn assert mismatch in drawn assert "asking for the arm: no" in drawn def test_the_raw_axes_are_still_shown_for_a_pad_that_does_not_fit(config): # The numbers are the evidence: they are what `Layout` gets corrected from. wrong = stick(axes=[0.0, 0.0, 0.0, -1.0, -1.0, -1.0]) drawn = probe.render(wrong, Sample(present=False), [0.0] * 6, config, "axis 3") assert "-1.000" in drawn assert "axes (6 reported)" in drawn