def test_composite_with_invalid_child_node_value(self, mock_load_yaml, mock_import): invalid_data = { "tasks_path": "foo.bar", "tree": { "sequence": [{ "retry": { "selector": [{ "task": "good_value", }, { "task": { "BAD_KEY": "BAD_VALUE" } }] } }, { "task": "another_good_value" }] } } mock_load_yaml.return_value = invalid_data bt = BehaviourTree("foobar.yaml") with self.assertRaises(ValidationError) as exc_context: bt.load() self.assertEqual(exc_context.exception.message, "{'BAD_KEY': 'BAD_VALUE'} is not of type 'string'")
def test_root_no_tree(self, mock_load_json, mock_import): invalid_data = {"tasks_path": "foo.bar"} mock_load_json.return_value = invalid_data bt = BehaviourTree("foobar.json") with self.assertRaises(ValidationError) as exc_context: bt.load() self.assertEqual(exc_context.exception.message, "'tree' is a required property") self.assertFalse(mock_import.import_module.called)
class TestGame(TestCase): def setUp(self): self.btree = BehaviourTree(YAML_MODEL_PATH) self.btree.load() def test_can_eat_no_retry_needed(self): character_data = { "coordinates": (2, 2), "food": ["apple", "orange"], } self.btree.execute(character_data) self.assertListEqual( self.btree.execution_path, [ ("am_i_hungry", True), ("have_i_food", True), ("NOT", ("enemies_nearby", False), True), ("eat", True) ] ) @patch("models.game.tasks.DB.query", side_effect=[["Bowser", "Revolver Ocelot"], ["Marlene"], []]) def test_can_eat_on_third_retry(self, mock_db_query): """Mock the db call to check for enemies around to pass on the 3rd attempt.""" character_data = { "coordinates": (2, 2), "food": ["apple", "orange"], } self.btree.execute(character_data) self.assertListEqual( self.btree.execution_path, [ ("am_i_hungry", True), ("have_i_food", True), ("NOT", ("enemies_nearby", True), False), ("NOT", ("enemies_nearby", True), False), ("NOT", ("enemies_nearby", False), True), ("eat", True) ] )
def test_decorator_with_invalid_child_node_key(self, mock_load_json, mock_import): invalid_data = { "tasks_path": "foo.bar", "tree": { "selector": [{ "task": "foo" }, { "not": { "BAD_KEY": "bar" } }] } } mock_load_json.return_value = invalid_data bt = BehaviourTree("foobar.json") with self.assertRaises(ValidationError) as exc_context: bt.load() self.assertEqual( exc_context.exception.message, "Additional properties are not allowed ('BAD_KEY' was unexpected)")
class TestFootball(TestCase): def setUp(self): self.btree = BehaviourTree(JSON_MODEL_PATH) self.btree.load() def test_attacker_can_shoot(self): game_data = { "attacker": { "name": "Mane", "coordinates": (0, 1) }, "opposition": [{ "name": "Jones", "coordinates": (0, 2) }], "teammates": [] } self.btree.execute(game_data) self.assertListEqual(self.btree.execution_path, [("check_have_space", True), ("check_close_to_goal", True), ("shoot", True)]) def test_attacker_cannot_shoot_but_can_pass(self): game_data = { "attacker": { "name": "Mane", "coordinates": (1, 0) # too far out to shoot }, "opposition": [{ "name": "Jones", "coordinates": (0, 1) }], "teammates": [{ "name": "Robertson", "coordinates": (1, 0) }] } self.btree.execute(game_data) self.assertListEqual(self.btree.execution_path, [("check_have_space", True), ("check_close_to_goal", False), ("check_have_space", True), ("check_teammate_nearby", True), ("NOT", ("check_nearby_teammates_marked", False), True), ("pass_ball", True)]) def test_attacker_cannot_shoot_cannot_pass_but_can_cross(self): game_data = { "attacker": { "name": "Mane", "coordinates": (0, 0) # too wide to shoot }, "opposition": [{ "name": "Jones", "coordinates": (0, 1) }], "teammates": [{ "name": "Firmino", "coordinates": (0, 1) # too far away to pass }] } self.btree.execute(game_data) self.assertListEqual(self.btree.execution_path, [("check_have_space", True), ("check_close_to_goal", False), ("check_have_space", True), ("check_teammate_nearby", False), ("check_have_space", True), ("check_in_crossing_position", True), ("cross", True)]) def test_attacker_can_only_go_backwards(self): game_data = { "attacker": { "name": "Mane", "coordinates": (2, 2) # too far out to shoot, cross }, "opposition": [{ "name": "Jones", "coordinates": (1, 1) }], "teammates": [{ "name": "Firmino", "coordinates": (0, 1) # too far away to pass }] } self.btree.execute(game_data) self.assertListEqual(self.btree.execution_path, [("check_have_space", True), ("check_close_to_goal", False), ("check_have_space", True), ("check_teammate_nearby", False), ("check_have_space", True), ("check_in_crossing_position", False), ("go_backwards", True)])