import importlib.util from pathlib import Path from tests._shared.repo_paths import find_repo_root def _load_module(module_name: str, relative_path: str): repo_root = find_repo_root(__file__) module_path = repo_root / relative_path spec = importlib.util.spec_from_file_location(module_name, module_path) module = importlib.util.module_from_spec(spec) assert spec.loader is not None spec.loader.exec_module(module) return module matcher_mod = _load_module( "oracle_action_matcher_position_under_test", "src/robomme/robomme_env/utils/oracle_action_matcher.py", ) class _Pose: def __init__(self, p): self.p = p class _Actor: def __init__(self, name, pose_p=None, use_get_pose=False): self.name = name self._pose = _Pose(pose_p) if pose_p is not None else None if not use_get_pose and self._pose is not None: self.pose = self._pose def get_pose(self): if self._pose is None: raise RuntimeError("missing pose") return self._pose def test_select_target_with_position_nearest_candidate(): actor_a = _Actor("A", [0.0, 0.0, 0.0]) actor_b = _Actor("B", [0.8, 0.0, 0.0]) actor_c = _Actor("C", [3.0, 0.0, 0.0]) result = matcher_mod.select_target_with_position( available=[actor_a, actor_b, actor_c], position_like=[1.0, 0.0, 0.0], ) assert result is not None assert result["name"] == "B" assert result["selection_mode"] == "nearest_position" assert abs(float(result["match_distance"]) - 0.2) < 1e-9 def test_select_target_with_position_skips_invalid_candidates(): actor_invalid = _Actor("invalid", None) actor_valid = _Actor("valid", [1.0, 2.0, 3.0], use_get_pose=True) result = matcher_mod.select_target_with_position( available=[actor_invalid, actor_valid], position_like=[1.2, 2.2, 3.1], ) assert result is not None assert result["name"] == "valid" def test_select_target_with_position_returns_none_without_valid_input(): actor_invalid = _Actor("invalid", None) res_invalid_position = matcher_mod.select_target_with_position( available=[_Actor("a", [0.0, 0.0, 0.0])], position_like=[0.0, 0.0], ) assert res_invalid_position is None res_invalid_candidates = matcher_mod.select_target_with_position( available=[actor_invalid], position_like=[0.0, 0.0, 0.0], ) assert res_invalid_candidates is None def test_select_target_with_position_tie_breaks_by_first_flattened_candidate(): actor_first = _Actor("first", [1.0, 0.0, 0.0]) actor_second = _Actor("second", [-1.0, 0.0, 0.0]) result = matcher_mod.select_target_with_position( available={"left": [actor_first], "right": [actor_second]}, position_like=[0.0, 0.0, 0.0], ) assert result is not None assert result["name"] == "first"