def make_pose_rel_to_parent(scene: Scene, project: Project, pose: Pose, parent_id: str) -> Pose: """ Transforms global Pose into Pose that is relative to a given parent (can be object or AP). :param scene: :param project: :param pose: :param parent_id: :return: """ if parent_id in scene.object_ids: parent_pose = scene.object(parent_id).pose elif parent_id in project.action_points_ids: parent_ap = project.action_point(parent_id) if parent_ap.parent: pose = make_pose_rel_to_parent(scene, project, pose, parent_ap.parent) parent_pose = Pose(parent_ap.position, Orientation()) else: raise Arcor2Exception("Unknown parent_id.") return make_pose_rel(parent_pose, pose)
def test_obj_relative_ap_global() -> None: scene = Scene("s1") # object rotated 90° clock-wise so1 = SceneObject( "so1", "WhatEver", Pose(Position(1, 0, 0), Orientation(0, 0, -0.707, 0.707))) scene.objects.append(so1) cached_scene = CachedScene(scene) project = Project("p1", scene.id) ap1 = ActionPoint("ap1", Position(1, 0, 0), parent=so1.id) project.action_points.append(ap1) ap2 = ActionPoint("ap2", Position(1, 0, 0), parent=ap1.id) no1 = NamedOrientation("o1", Orientation()) ap2.orientations.append(no1) project.action_points.append(ap2) cached_project = CachedProject(project) make_relative_ap_global(cached_scene, cached_project, ap2) check_ap(ap2) assert ap2.position == Position(1, -2, 0) assert so1.pose assert no1.orientation == so1.pose.orientation make_global_ap_relative(cached_scene, cached_project, ap2, ap1.id) assert ap2.position == Position(1, 0, 0) assert no1.orientation == Orientation() check_ap(ap2)
def make_global_ap_relative(scene: Scene, project: Project, ap: ProjectActionPoint, parent_id: str) -> None: """ Transforms (in place) global AP into a relative one with given parent (can be object or another AP). :param scene: :param project: :param ap: :param parent_id: :return: """ assert project.scene_id == scene.id if parent_id in scene.object_ids: new_parent_pose = scene.object(parent_id).pose elif parent_id in project.action_points_ids: parent_ap = project.action_point(parent_id) if parent_ap.parent: make_global_ap_relative(scene, project, ap, parent_ap.parent) new_parent_pose = Pose(parent_ap.position, Orientation()) else: raise Arcor2Exception("Unknown parent_id.") ap.position = make_pose_rel(new_parent_pose, Pose(ap.position, Orientation())).position for ori in ap.orientations: ori.orientation = make_orientation_rel(new_parent_pose.orientation, ori.orientation) ap.parent = parent_id
def make_relative_ap_global(scene: Scene, project: Project, ap: ProjectActionPoint) -> None: """ Transforms (in place) relative AP into a global one. :param scene: :param project: :param ap: :return: """ if not ap.parent: return if ap.parent in scene.object_ids: old_parent_pose = scene.object(ap.parent).pose elif ap.parent in project.action_points_ids: old_parent_pose = Pose(project.action_point(ap.parent).position, Orientation()) else: raise Arcor2Exception("AP has unknown parent_id.") ap.position = make_pose_abs(old_parent_pose, Pose(ap.position, Orientation())).position for ori in ap.orientations: ori.orientation = make_orientation_abs(old_parent_pose.orientation, ori.orientation) if ap.parent in project.action_points_ids: parent_ap = project.action_point(ap.parent) if parent_ap.parent: ap.parent = parent_ap.parent make_relative_ap_global(scene, project, ap) ap.parent = None
def test_make_relative_ap_global_and_relative_again(): scene = Scene("s1", "s1") scene.objects.append( SceneObject("so1", "so1", "WhatEver", Pose(Position(3, 0, 0), Orientation()))) project = Project("p1", "p1", "s1") project.action_points.append( ProjectActionPoint("ap1", "ap1", Position(-1, 0, 0), parent="so1")) project.action_points.append( ProjectActionPoint("ap2", "ap2", Position(-1, 0, 0), parent="ap1")) ap3 = ProjectActionPoint("ap3", "ap3", Position(-1, 0, 0), parent="ap2") project.action_points.append(ap3) make_relative_ap_global(scene, project, ap3) assert ap3.parent is None assert ap3.position.x == .0 make_global_ap_relative(scene, project, ap3, "ap2") assert ap3.parent == "ap2" assert ap3.position.x == -1 ap3.parent = "something_unknown" with pytest.raises(Arcor2Exception): make_relative_ap_global(scene, project, ap3)
def test_blind_branch() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac4) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append(LogicItem(ac1.id, ac3.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac4.id)) project.logic.append(LogicItem(ac4.id, LogicItem.END)) with pytest.raises(SourceException, match=f"Action {ac3.name} has no outputs."): program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene))
def test_constant() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) const_value = 1234 const = ProjectParameter("int_const", "integer", json.dumps(const_value)) project.parameters.append(const) ac1 = Action( "ac1", f"{obj.id}/test_par", flows=[Flow()], parameters=[ ActionParameter("param", ActionParameter.TypeEnum.CONSTANT, json.dumps(const.id)) ], ) ap1.actions.append(ac1) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) assert f"{const.name} = {const_value}" in src assert f"test_name.{Test.test_par.__name__}({const.name}, an='ac1')" in src
async def update_scene(scene: Scene) -> datetime: assert scene.id ret = await ps.update_scene(scene) scene.modified = ret if not scene.created: scene.created = scene.modified _scenes_list.listing[scene.id] = IdDesc(scene.id, scene.name, scene.created, scene.modified, scene.description) _scenes[scene.id] = deepcopy(scene) _scenes[scene.id].int_modified = None return ret
def test_slots() -> None: """Tests whether classes from cached module uses __slots__.""" s = Scene("") p = Project("", s.id) assert not hasattr(CachedScene(s), "__dict__") assert not hasattr(CachedProject(p), "__dict__") assert not hasattr(UpdateableCachedScene(s), "__dict__") assert not hasattr(UpdateableCachedProject(p), "__dict__")
def test_get_value() -> None: p = Pose(Position(1, 2, 3), Orientation(1, 0, 0, 0)) scene = Scene("s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) project.action_points.append(ap1) ap2 = ActionPoint("ap2", Position(), parent=ap1.id) project.action_points.append(ap2) ori1 = NamedOrientation("ori1", p.orientation) ap2.orientations.append(ori1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, PosePlugin.type_name(), json.dumps(ori1.id)), ActionParameter(invalid_param_name, PosePlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): PosePlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, invalid_param_name) value = PosePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, param_name) exe_value = PosePlugin.parameter_execution_value(type_defs, cscene, cproject, ac1.id, param_name) assert value == value assert value != exe_value
def test_get_value() -> None: scene = Scene("s1", "s1") obj = SceneObject("test_name", TestObject.__name__) prj = ProjectRobotJoints("name", obj.id, [Joint("name", 0.333)]) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) ap1.robot_joints.append(prj) project.action_points.append(ap1) invalid_param_name = "invalid_param" act = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, JointsPlugin.type_name(), json.dumps(prj.id)), ActionParameter(invalid_param_name, JointsPlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(act) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, "non_sense") with pytest.raises(Arcor2Exception): JointsPlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, invalid_param_name) value = JointsPlugin.parameter_value(type_defs, cscene, cproject, act.id, param_name) exe_value = JointsPlugin.parameter_execution_value(type_defs, cscene, cproject, act.id, param_name) assert value == value assert value == exe_value
def test_get_value() -> None: img = Image.new("RGB", (320, 240)) scene = Scene("s1", "s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position(1, 0, 0)) project.action_points.append(ap1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, ImagePlugin.type_name(), ImagePlugin.value_to_json(img)), ActionParameter(invalid_param_name, ImagePlugin.type_name(), json.dumps("non_sense")), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): ImagePlugin.parameter_value(type_defs, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, invalid_param_name) value = ImagePlugin.parameter_value(type_defs, cscene, cproject, ac1.id, param_name) exe_value = ImagePlugin.parameter_execution_value(type_defs, cscene, cproject, ac1.id, param_name) assert value == value assert value == exe_value
def test_get_value(self, val: str) -> None: scene = Scene("s1") obj = SceneObject("test_name", TestObject.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) invalid_param_name = "invalid_param" ac1 = Action( "ac1", f"{obj.id}/{TestObject.action.__name__}", parameters=[ ActionParameter(param_name, StringPlugin.type_name(), StringPlugin.value_to_json(val)), ActionParameter(invalid_param_name, StringPlugin.type_name(), json.dumps(666)), ], ) ap1.actions.append(ac1) cscene = CachedScene(scene) cproject = CachedProject(project) with pytest.raises(Arcor2Exception): StringPlugin.parameter_value({}, cscene, cproject, ac1.id, "non_sense") with pytest.raises(Arcor2Exception): StringPlugin.parameter_value({}, cscene, cproject, "non_sense", param_name) with pytest.raises(ParameterPluginException): StringPlugin.parameter_value({}, cscene, cproject, ac1.id, invalid_param_name) value = StringPlugin.parameter_value({}, cscene, cproject, ac1.id, param_name) exe_value = StringPlugin.parameter_execution_value({}, cscene, cproject, ac1.id, param_name) assert value == val assert value == exe_value
def test_make_relative_ap_global_and_relative_again() -> None: scene = Scene("s1") so1 = SceneObject("so1", "WhatEver", Pose(Position(3, 0, 0), Orientation())) scene.objects.append(so1) cached_scene = CachedScene(scene) project = Project("p1", scene.id) ap1 = ActionPoint("ap1", Position(-1, 0, 0), parent=so1.id) project.action_points.append(ap1) ap2 = ActionPoint("ap2", Position(-1, 0, 0), parent=ap1.id) project.action_points.append(ap2) ap3 = ActionPoint( "ap3", Position(-1, 0, 0), parent=ap2.id, orientations=[NamedOrientation("bla", random_orientation())]) project.action_points.append(ap3) cached_project = CachedProject(project) assert ap3.parent ap3_parent = get_parent_pose(cached_scene, cached_project, ap3.parent) assert Pose(ap2.position, Orientation()) == ap3_parent.pose assert ap3_parent.parent_id == ap1.id make_relative_ap_global(cached_scene, cached_project, ap3) check_ap(ap3) assert ap3.parent is None assert ap3.position.x == 0.0 # type: ignore make_global_ap_relative(cached_scene, cached_project, ap3, ap2.id) check_ap(ap3) assert ap3.parent == ap2.id assert ap3.position.x == -1 ap3.parent = "something_unknown" with pytest.raises(Arcor2Exception): make_relative_ap_global(cached_scene, cached_project, ap3)
def test_prev_result() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/{Test.get_int.__name__}", flows=[Flow(outputs=["res"])]) ap1.actions.append(ac1) ac2 = Action( "ac2", f"{obj.id}/{Test.test_par.__name__}", flows=[Flow()], parameters=[ ActionParameter("param", ActionParameter.TypeEnum.LINK, json.dumps(f"{ac1.id}/default/0")) ], ) ap1.actions.append(ac2) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append(LogicItem(ac1.id, ac2.id)) project.logic.append(LogicItem(ac2.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) assert f"res = test_name.{Test.get_int.__name__}(an='{ac1.name}')" in src assert f"test_name.{Test.test_par.__name__}(res, an='{ac2.name}')" in src # test wrong order of logic project.logic.clear() project.logic.append(LogicItem(LogicItem.START, ac2.id)) project.logic.append(LogicItem(ac2.id, ac1.id)) project.logic.append(LogicItem(ac1.id, LogicItem.END)) with pytest.raises(SourceException): program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene))
def add_logic_to_loop(tree: Module, scene: Scene, project: Project) -> None: loop = main_loop_body(tree) try: actions_cache, first_action_id, last_action_id = get_actions_cache( project) except ProjectException as e: raise SourceException(e) if first_action_id is None: raise SourceException("'start' action not found.") if last_action_id is None: raise SourceException("'end' action not found.") next_action_id = first_action_id while True: act = actions_cache[next_action_id] if len(loop) == 1 and isinstance(loop[0], Pass): # pass is not necessary now loop.clear() ac_obj, ac_type = act.type.split('/') # for scene objects, convert ID to name try: ac_obj = scene.object(ac_obj).name except Arcor2Exception: pass append_method_call(loop, fix_object_name(ac_obj), ac_type, [get_name_attr("res", clean(act.name))], []) if act.id == last_action_id: break next_action_id = act.outputs[0].default
def value(cls, type_defs: TypesDict, scene: Scene, project: Project, action_id: str, parameter_id: str) -> \ ProjectRobotJoints: ap, action = project.action_point_and_action(action_id) param = action.parameter(parameter_id) joints_id = cls.param_value(param) robot_id, action_method_name = action.parse_type() robot_type = scene.object_or_service(robot_id) if issubclass(type_defs[robot_type.type], RobotService): for param in action.parameters: if param.id == "robot_id": robot_id = json.loads(param.value) break else: raise ParameterPluginException( f"Parameter {param.id} of action {action.id} depends on" f" 'robot_id' parameter, which could not be found.") return ap.joints_for_robot(robot_id, joints_id)
def value(cls, type_defs: TypesDict, scene: Scene, project: Project, action_id: str, parameter_id: str) -> Enum: action = project.action(action_id) param = action.parameter(parameter_id) obj_id, action_type = action.parse_type() obj_type = type_defs[scene.object_or_service(obj_id).type] method = getattr(obj_type, action_type) ttype = get_type_hints(method)[param.id] if not issubclass(ttype, cls.type()): raise ParameterPluginException( f"Type {ttype.__name__} is not subclass of {cls.type().__name__}." ) try: return ttype(json.loads(param.value)) except ValueError: raise ParameterPluginException( f"Parameter {parameter_id} of action {action.name} has invalid value." )
def test_list_problems(start_processes: None, ars: ARServer) -> None: """This is a test for a bug in get_scene_problems and get_project_problems functions. Because of the bug, the RPC returned result=False when there was non-existing ObjectType. :param start_processes: :param ars: :return: """ upload_def(DummyMultiArmRobot ) # OT has to exist first, otherwise scene can't be stored invalid_scene_1 = Scene("invalidScene", objects=[ SceneObject("invalidObject", DummyMultiArmRobot.__name__, Pose()) ]) invalid_project_1 = Project("invalidProject", invalid_scene_1.id) project_service.update_scene(invalid_scene_1) project_service.update_project(invalid_project_1) project_service.delete_object_type( DummyMultiArmRobot.__name__) # now the OT can be deleted # initial event show_main_screen_event = event(ars, events.c.ShowMainScreen) assert show_main_screen_event.data assert show_main_screen_event.data.what == events.c.ShowMainScreen.Data.WhatEnum.ScenesList scenes = ars.call_rpc(rpc.s.ListScenes.Request(get_id()), rpc.s.ListScenes.Response) assert scenes.result assert scenes.data assert len(scenes.data) == 1 assert scenes.data[0].id == invalid_scene_1.id assert scenes.data[0].name == invalid_scene_1.name assert scenes.data[0].problems assert len(scenes.data[0].problems) == 1 projects = ars.call_rpc(rpc.p.ListProjects.Request(get_id()), rpc.p.ListProjects.Response) assert projects.result assert projects.data assert len(projects.data) == 1 assert projects.data[0].id == invalid_project_1.id assert projects.data[0].name == invalid_project_1.name assert projects.data[0].problems assert len(projects.data[0].problems) == 1 upload_def(DummyMultiArmRobot) # now the ObjectType exists, so the scene/project should be ok scenes2 = ars.call_rpc(rpc.s.ListScenes.Request(get_id()), rpc.s.ListScenes.Response) assert scenes2.result assert scenes2.data assert len(scenes2.data) == 1 assert scenes2.data[0].id == invalid_scene_1.id assert scenes2.data[0].name == invalid_scene_1.name assert scenes2.data[0].problems is None projects2 = ars.call_rpc(rpc.p.ListProjects.Request(get_id()), rpc.p.ListProjects.Response) assert projects2.result assert projects2.data assert len(projects2.data) == 1 assert projects2.data[0].id == invalid_project_1.id assert projects2.data[0].name == invalid_project_1.name assert projects2.data[0].problems is None
def test_branched_output_2() -> None: scene = Scene("s1") obj = SceneObject("test_name", Test.__name__) scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow(outputs=["bool2_res"])]) ap1.actions.append(ac4) ac5 = Action("ac5", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac5) ac6 = Action("ac6", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac6) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append( LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append( LogicItem(ac1.id, ac4.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac3.id)) project.logic.append(LogicItem(ac3.id, ac6.id)) project.logic.append( LogicItem(ac4.id, ac5.id, ProjectLogicIf(f"{ac4.id}/default/0", json.dumps(True)))) project.logic.append(LogicItem(ac5.id, ac6.id)) project.logic.append(LogicItem(ac6.id, LogicItem.END)) project.logic.append( LogicItem(ac4.id, LogicItem.END, ProjectLogicIf(f"{ac4.id}/default/0", json.dumps(False)))) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) parse(src) """ bool_res = test_name.test(res.ac1) if (bool_res == False): bool2_res = test_name.test(res.ac4) if (bool2_res == False): continue elif (bool2_res == True): test_name.test(res.ac5) elif (bool_res == True): test_name.test(res.ac2) test_name.test(res.ac3) test_name.test(res.ac6) """ spl = src.splitlines() # it has to be robust against changed order of blocks ac1_idx = subs_index(spl, "bool_res = test_name.test(an='ac1')") if_bool_res_false_idx = subs_index(spl, "if (bool_res == False):") assert if_bool_res_false_idx > ac1_idx assert cntsp(spl[ac1_idx]) == cntsp(spl[if_bool_res_false_idx]) bool2_res_idx = subs_index(spl, "bool2_res = test_name.test(an='ac4')") assert bool2_res_idx > if_bool_res_false_idx assert cntsp(spl[if_bool_res_false_idx]) == cntsp(spl[bool2_res_idx]) - TAB if_bool_2_res_false_idx = subs_index(spl, "if (bool2_res == False):") assert cntsp(spl[if_bool_2_res_false_idx]) == cntsp(spl[bool2_res_idx]) assert if_bool_2_res_false_idx > bool2_res_idx assert "continue" in spl[if_bool_2_res_false_idx + 1] assert cntsp( spl[bool2_res_idx]) == cntsp(spl[if_bool_2_res_false_idx + 1]) - TAB if_bool_2_res_true_idx = subs_index(spl, "if (bool2_res == True):") assert if_bool_2_res_true_idx > bool2_res_idx assert "test_name.test(an='ac5')" in spl[if_bool_2_res_true_idx + 1] assert cntsp(spl[if_bool_2_res_true_idx]) == cntsp( spl[if_bool_2_res_true_idx + 1]) - TAB if_bool_res_true_idx = subs_index(spl, "if (bool_res == True):") assert if_bool_res_true_idx > ac1_idx assert cntsp(spl[ac1_idx]) == cntsp(spl[if_bool_res_true_idx]) assert "test_name.test(an='ac2')" in spl[if_bool_res_true_idx + 1] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 1]) - TAB assert "test_name.test(an='ac3')" in spl[if_bool_res_true_idx + 2] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 2]) - TAB ac6_idx = subs_index(spl, "test_name.test(an='ac6')") assert cntsp(spl[ac1_idx]) == cntsp(spl[ac6_idx]) assert ac6_idx > if_bool_2_res_false_idx assert ac6_idx > if_bool_2_res_true_idx
def test_branched_output() -> None: scene = Scene("s1") obj = SceneObject("test_name", "Test") scene.objects.append(obj) project = Project("p1", "s1") ap1 = ActionPoint("ap1", Position()) project.action_points.append(ap1) ac1 = Action("ac1", f"{obj.id}/test", flows=[Flow(outputs=["bool_res"])]) ap1.actions.append(ac1) ac2 = Action("ac2", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac2) ac3 = Action("ac3", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac3) ac4 = Action("ac4", f"{obj.id}/test", flows=[Flow()]) ap1.actions.append(ac4) project.logic.append(LogicItem(LogicItem.START, ac1.id)) project.logic.append( LogicItem(ac1.id, ac2.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(True)))) project.logic.append( LogicItem(ac1.id, ac3.id, ProjectLogicIf(f"{ac1.id}/default/0", json.dumps(False)))) project.logic.append(LogicItem(ac2.id, ac4.id)) project.logic.append(LogicItem(ac3.id, ac4.id)) project.logic.append(LogicItem(ac4.id, LogicItem.END)) src = program_src({Test.__name__: Test}, CachedProject(project), CachedScene(scene)) parse(src) """ bool_res = test_name.test(res.ac1) if bool_res == False: test_name.test(res.ac3) elif bool_res == True: test_name.test(res.ac2) test_name.test(res.ac4) """ spl = src.splitlines() ac1_idx = subs_index(spl, "bool_res = test_name.test(an='ac1')") if_bool_res_false_idx = subs_index(spl, "if bool_res == False:") assert if_bool_res_false_idx > ac1_idx assert cntsp(spl[if_bool_res_false_idx]) == cntsp(spl[ac1_idx]) assert "test_name.test(an='ac3')" in spl[if_bool_res_false_idx + 1] assert cntsp(spl[if_bool_res_false_idx]) == cntsp( spl[if_bool_res_false_idx + 1]) - TAB if_bool_res_true_idx = subs_index(spl, "if bool_res == True:") assert if_bool_res_true_idx > ac1_idx assert cntsp(spl[if_bool_res_true_idx]) == cntsp(spl[ac1_idx]) assert "test_name.test(an='ac2')" in spl[if_bool_res_true_idx + 1] assert cntsp(spl[if_bool_res_true_idx]) == cntsp( spl[if_bool_res_true_idx + 1]) - TAB ac4_idx = subs_index(spl, "test_name.test(an='ac4')") assert ac4_idx > if_bool_res_false_idx assert ac4_idx > if_bool_res_true_idx assert cntsp(spl[ac4_idx]) == cntsp(spl[ac1_idx])
def scene() -> Scene: scene = Scene("s1", "s1") scene.objects.append(obj) return scene