diff --git a/game/common/avatar.py b/game/common/avatar.py index a19f7d70..a7112fa1 100644 --- a/game/common/avatar.py +++ b/game/common/avatar.py @@ -4,6 +4,7 @@ from game.common.game_object import GameObject from game.quarry_rush.ability.emp_active_ability import EMPActiveAbility from game.quarry_rush.ability.landmine_active_ability import LandmineActiveAbility +from game.quarry_rush.ability.trap_defusal_active_ability import TrapDefusalActiveAbility from game.quarry_rush.tech.tech import TechInfo from game.utils.vector import Vector from game.quarry_rush.tech.tech_tree import TechTree @@ -154,6 +155,7 @@ def __init__(self, company: Company = Company.CHURCH, position: Vector | None = self.dynamite_active_ability: DynamiteActiveAbility = DynamiteActiveAbility() self.landmine_active_ability: LandmineActiveAbility = LandmineActiveAbility() self.emp_active_ability: EMPActiveAbility = EMPActiveAbility() + self.trap_defusal_active_ability: TrapDefusalActiveAbility = TrapDefusalActiveAbility() @property def company(self) -> Company: @@ -361,7 +363,7 @@ def can_place_emp(self) -> bool: return self.abilities['EMPs'] and self.emp_active_ability.is_usable and not self.abilities['Landmines'] def can_defuse_trap(self) -> bool: - return self.abilities['Trap Defusal'] + return self.abilities['Trap Defusal'] and self.trap_defusal_active_ability.is_usable # method to return the opposing team based on the avatar's company def get_opposing_team(self) -> Company: diff --git a/game/common/enums.py b/game/common/enums.py index 86d54e2b..8f00547a 100644 --- a/game/common/enums.py +++ b/game/common/enums.py @@ -49,6 +49,7 @@ class ObjectType(Enum): TRAP = auto() # 31 LANDMINE = auto() # 32 EMP = auto() # 33 + TRAP_DEFUSAL_ACTIVE_ABILITY = auto() # 34 class ActionType(Enum): diff --git a/game/controllers/defuse_controller.py b/game/controllers/defuse_controller.py index f5317a61..1630cf59 100644 --- a/game/controllers/defuse_controller.py +++ b/game/controllers/defuse_controller.py @@ -10,6 +10,9 @@ def __init__(self) -> None: super().__init__() def handle_actions(self, action: ActionType, client: Player, world: GameBoard): + if not client.avatar.can_defuse_trap(): # return if not usable + return + temp_vector: Vector match action: case ActionType.DEFUSE_UP: diff --git a/game/controllers/mine_controller.py b/game/controllers/mine_controller.py index fa6eea11..10d147a6 100644 --- a/game/controllers/mine_controller.py +++ b/game/controllers/mine_controller.py @@ -22,6 +22,10 @@ def handle_actions(self, action: ActionType, client: Player, world: GameBoard) - will be taken, and it stops there. If no copium is found, None will be returned. """ + # don't mine anything if the inventory is full + if len(world.inventory_manager.get_inventory(client.avatar.company)) == 50: + return + match action: case ActionType.MINE: client.avatar.state = 'mining' diff --git a/game/quarry_rush/ability/dynamite_active_ability.py b/game/quarry_rush/ability/dynamite_active_ability.py index 79417855..a50bf3a4 100644 --- a/game/quarry_rush/ability/dynamite_active_ability.py +++ b/game/quarry_rush/ability/dynamite_active_ability.py @@ -5,6 +5,8 @@ class DynamiteActiveAbility(ActiveAbility): - def __init__(self, cooldown: int = 1, fuse: int = 0): + def __init__(self, cooldown: int = 4, fuse: int = 0): super().__init__() self.object_type = ObjectType.DYNAMITE_ACTIVE_ABILITY + self.cooldown = cooldown + self.fuse = fuse # default = 0 to be available right after purchase diff --git a/game/quarry_rush/ability/emp_active_ability.py b/game/quarry_rush/ability/emp_active_ability.py index cc480bb2..e96a5f7d 100644 --- a/game/quarry_rush/ability/emp_active_ability.py +++ b/game/quarry_rush/ability/emp_active_ability.py @@ -4,8 +4,8 @@ class EMPActiveAbility(ActiveAbility): - def __init__(self, cooldown: int = 1, fuse: int = 0): + def __init__(self, cooldown: int = 4, fuse: int = 0): super().__init__() self.object_type: ObjectType = ObjectType.EMP_ACTIVE_ABILITY self.cooldown: int = cooldown - self.fuse: int = fuse + self.fuse: int = fuse # default = 0 to be available right after purchase diff --git a/game/quarry_rush/ability/landmine_active_ability.py b/game/quarry_rush/ability/landmine_active_ability.py index f429d5e8..4abb637b 100644 --- a/game/quarry_rush/ability/landmine_active_ability.py +++ b/game/quarry_rush/ability/landmine_active_ability.py @@ -4,8 +4,8 @@ class LandmineActiveAbility(ActiveAbility): - def __init__(self, cooldown: int = 1, fuse: int = 0): + def __init__(self, cooldown: int = 6, fuse: int = 0): super().__init__() self.object_type: ObjectType = ObjectType.LANDMINE_ACTIVE_ABILITY self.cooldown: int = cooldown - self.fuse: int = fuse + self.fuse: int = fuse # default = 0 to be available right after purchase diff --git a/game/quarry_rush/ability/trap_defusal_active_ability.py b/game/quarry_rush/ability/trap_defusal_active_ability.py new file mode 100644 index 00000000..1a609d05 --- /dev/null +++ b/game/quarry_rush/ability/trap_defusal_active_ability.py @@ -0,0 +1,10 @@ +from game.quarry_rush.ability.active_ability import ActiveAbility +from game.common.enums import ObjectType + + +class TrapDefusalActiveAbility(ActiveAbility): + def __init__(self, cooldown: int = 0, fuse: int = 0): + super().__init__() + self.object_type = ObjectType.TRAP_DEFUSAL_ACTIVE_ABILITY + self.cooldown = cooldown # default = 0 to always be available + self.fuse = fuse # default = 0 to be available right after purchase diff --git a/game/test_suite/tests/test_avatar.py b/game/test_suite/tests/test_avatar.py index af1de687..abdce5e6 100644 --- a/game/test_suite/tests/test_avatar.py +++ b/game/test_suite/tests/test_avatar.py @@ -168,6 +168,7 @@ def test_unlock_dynamite(self): self.avatar.buy_new_tech('Dynamite') self.assertTrue(self.avatar.is_researched('Improved Mining')) self.assertTrue(self.avatar.is_researched('Dynamite')) + self.assertTrue(self.avatar.can_place_dynamite()) # Buying Landmines will return False if the tree hasn't developed to it yet def test_unlock_landmines_fail(self): @@ -181,6 +182,7 @@ def test_unlock_landmines(self): self.assertTrue(self.avatar.is_researched('Improved Mining')) self.assertTrue(self.avatar.is_researched('Dynamite')) self.assertTrue(self.avatar.is_researched('Landmines')) + self.assertTrue(self.avatar.can_place_landmine()) # Buying EMPs will return False if the tree hasn't developed to it yet def test_unlock_emps_fail(self): @@ -197,6 +199,7 @@ def test_unlock_emps(self): self.assertTrue(self.avatar.is_researched('Landmines')) self.assertTrue(self.avatar.is_researched('EMPs')) self.assertFalse(self.avatar.is_researched('Trap Defusal')) + self.assertTrue(self.avatar.can_place_emp()) # Buying Trap Detection will return False if the tree hasn't developed to it yet def test_unlock_trap_defusal_fail(self): @@ -213,6 +216,7 @@ def test_unlock_trap_defusal(self): self.assertTrue(self.avatar.is_researched('Landmines')) self.assertTrue(self.avatar.is_researched('Trap Defusal')) self.assertFalse(self.avatar.is_researched('EMPs')) + self.assertTrue(self.avatar.can_defuse_trap()) # Tests getting the researched techs def test_get_researched_techs(self): @@ -246,6 +250,11 @@ def test_avatar_json(self): self.assertEqual(self.avatar.emp_active_ability.cooldown, avatar.emp_active_ability.cooldown) self.assertEqual(self.avatar.emp_active_ability.is_usable, avatar.emp_active_ability.is_usable) + self.assertEqual(self.avatar.trap_defusal_active_ability.fuse, avatar.trap_defusal_active_ability.fuse) + self.assertEqual(self.avatar.trap_defusal_active_ability.cooldown, avatar.trap_defusal_active_ability.cooldown) + self.assertEqual(self.avatar.trap_defusal_active_ability.is_usable, + avatar.trap_defusal_active_ability.is_usable) + # other_tree: dict = self.avatar.get_tech_tree().to_json() # for tech in self.avatar.get_tech_tree().tech_names(): # self.assertEqual(other_tree[tech], self.avatar.get_tech_tree().is_researched(tech)) diff --git a/game/test_suite/tests/test_defuse_controller.py b/game/test_suite/tests/test_defuse_controller.py new file mode 100644 index 00000000..bb81faa8 --- /dev/null +++ b/game/test_suite/tests/test_defuse_controller.py @@ -0,0 +1,63 @@ +import unittest + +from game.common.action import ActionType +from game.common.avatar import Avatar +from game.common.game_object import GameObject +from game.common.map.game_board import GameBoard +from game.common.player import Player +from game.controllers.defuse_controller import DefuseController +from game.quarry_rush.entity.placeable.traps import Landmine, EMP +from game.utils.vector import Vector + + +class TestDefuseController(unittest.TestCase): + def setUp(self): + self.avatar: Avatar = Avatar() + self.avatar.science_points = 5000 # to unlock trap defusal + self.avatar.buy_new_tech('Improved Mining') + self.avatar.buy_new_tech('Dynamite') + self.avatar.buy_new_tech('Landmines') + self.avatar.buy_new_tech('Trap Defusal') + + self.defuse_controller: DefuseController = DefuseController() + self.locations: dict[tuple[Vector], list[GameObject]] = { + (Vector(1, 0),): [Landmine()], # above avatar + (Vector(0, 1),): [EMP()], # left of avatar + (Vector(1, 1),): [self.avatar], # center + (Vector(2, 1),): [EMP()], # right of avatar + (Vector(1, 2),): [Landmine()] # below avatar + } + + # make a 3x3 game board + self.world: GameBoard = GameBoard(0, Vector(3, 3), self.locations, False) + self.client = Player(None, None, [], self.avatar) + self.world.generate_map() + + # test defusing a trap above works + def test_defuse_trap_above(self): + self.assertTrue(self.world.game_map[0][1].is_occupied_by_game_object(Landmine)) + self.defuse_controller.handle_actions(ActionType.DEFUSE_UP, self.client, self.world) + self.assertFalse(self.world.game_map[0][1].is_occupied_by_game_object(Landmine)) # remember (y, x) coordinates + + # test defusing a trap to the right works + def test_defuse_trap_to_right(self): + self.assertTrue(self.world.game_map[1][2].is_occupied_by_game_object(EMP)) + self.defuse_controller.handle_actions(ActionType.DEFUSE_RIGHT, self.client, self.world) + self.assertFalse(self.world.game_map[1][2].is_occupied_by_game_object(EMP)) + + # test defusing a trap below works + def test_defuse_trap_below(self): + self.assertTrue(self.world.game_map[2][1].is_occupied_by_game_object(Landmine)) + self.defuse_controller.handle_actions(ActionType.DEFUSE_DOWN, self.client, self.world) + self.assertFalse(self.world.game_map[2][1].is_occupied_by_game_object(Landmine)) + + # test defusing a trap to the left works + def test_defuse_trap_to_left(self): + self.assertTrue(self.world.game_map[1][0].is_occupied_by_game_object(EMP)) + self.defuse_controller.handle_actions(ActionType.DEFUSE_LEFT, self.client, self.world) + self.assertFalse(self.world.game_map[1][0].is_occupied_by_game_object(EMP)) + + # test defusing the same spot causes no errors + def test_defuse_twice(self): + self.test_defuse_trap_above() + self.assertFalse(self.world.game_map[0][1].is_occupied_by_game_object(Landmine)) \ No newline at end of file diff --git a/game/test_suite/tests/test_dynamite_active_ability.py b/game/test_suite/tests/test_dynamite_active_ability.py index 7a7cad31..82d9ae13 100644 --- a/game/test_suite/tests/test_dynamite_active_ability.py +++ b/game/test_suite/tests/test_dynamite_active_ability.py @@ -1,25 +1,17 @@ import unittest from game.quarry_rush.ability.dynamite_active_ability import DynamiteActiveAbility -from game.utils.vector import Vector class TestDynamiteActiveAbility(unittest.TestCase): - """ - This is class that tests the Active Ability + This is class that tests the Dynamite Active Ability """ + # set up def setUp(self) -> None: self.dynamite_active_ability = DynamiteActiveAbility() - self.name: str = "" self.cooldown: int = 1 - # test: name - def test_name(self): - self.name = "" - self.dynamite_active_ability.name = "" - self.assertEqual(self.dynamite_active_ability.name, self.name) - # test: cooldown def test_cooldown(self): self.cooldown = 1 @@ -68,22 +60,6 @@ def test_fuse_fail_negative(self): self.dynamite_active_ability.fuse = -1 self.assertEqual(str(e.exception), 'DynamiteActiveAbility.fuse cannot be negative') - # test: position - def test_dynamite_active_ability_set_position(self): - self.dynamite_active_ability.position = Vector(10, 10) - self.assertEqual(str(self.dynamite_active_ability.position), str(Vector(10, 10))) - - # test: position none - def test_dynamite_active_ability_set_position_None(self): - self.dynamite_active_ability.position = None - self.assertEqual(self.dynamite_active_ability.position, None) - - # fail test: position cannot be anything else - # def test_dynamite_active_ability_set_position_fail(self): - # with self.assertRaises(ValueError) as e: - # self.dynamite_active_ability.position = 10 - # self.assertEqual(str(e.exception), 'DynamiteActiveAbility.position must be a Vector or None.') - # test: for placing dynamite def test_placing_dynamite(self): self.dynamite_active_ability.placing_dynamite = False diff --git a/game/test_suite/tests/test_emp_active_ability.py b/game/test_suite/tests/test_emp_active_ability.py new file mode 100644 index 00000000..0db4f871 --- /dev/null +++ b/game/test_suite/tests/test_emp_active_ability.py @@ -0,0 +1,67 @@ +import unittest +from game.quarry_rush.ability.emp_active_ability import EMPActiveAbility + + +class TestEMPActiveAbility(unittest.TestCase): + """ + This is class that tests the Trap Defusal Active Ability + """ + + # set up + def setUp(self) -> None: + self.emp_active_ability: EMPActiveAbility = EMPActiveAbility() + + # test: cooldown + def test_cooldown(self): + self.emp_active_ability.cooldown = 1 + self.assertEqual(self.emp_active_ability.cooldown, 1) + + # fail test: cooldown CANT be null + def test_cooldown_fail_null(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.cooldown = None + self.assertEqual(str(e.exception), 'EMPActiveAbility.cooldown must be an int') + + # fail test: cooldown cant be anything else + def test_cooldown_fail_str(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.cooldown = "" + self.assertEqual(str(e.exception), 'EMPActiveAbility.cooldown must be an int') + + # fail test: cooldown cannot be negative + def test_cooldown_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.cooldown = -1 + self.assertEqual(str(e.exception), 'EMPActiveAbility.cooldown cannot be negative') + + # test: fuse + def test_fuse(self): + self.fuse = 1 + self.emp_active_ability.fuse = 1 + self.assertEqual(self.emp_active_ability.fuse, self.fuse) + + # fail test: fuse CANT be null + def test_fuse_fail_null(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.fuse = None + self.assertEqual(str(e.exception), 'EMPActiveAbility.fuse must be an int') + + # fail test: fuse cannot be anything else + def test_fuse_fail_str(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.fuse = "" + self.assertEqual(str(e.exception), 'EMPActiveAbility.fuse must be an int') + + # fail test: fuse cannot be negative + def test_fuse_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.emp_active_ability.fuse = -1 + self.assertEqual(str(e.exception), 'EMPActiveAbility.fuse cannot be negative') + + # test: json + def test_emp_active_ability_json(self): + data: dict = self.emp_active_ability.to_json() + emp_active_ability: EMPActiveAbility = EMPActiveAbility().from_json(data) + self.assertEqual(self.emp_active_ability.cooldown, emp_active_ability.cooldown) + self.assertEqual(self.emp_active_ability.fuse, emp_active_ability.fuse) + self.assertEqual(self.emp_active_ability.object_type, emp_active_ability.object_type) diff --git a/game/test_suite/tests/test_landmine_active_ability.py b/game/test_suite/tests/test_landmine_active_ability.py new file mode 100644 index 00000000..1da0de37 --- /dev/null +++ b/game/test_suite/tests/test_landmine_active_ability.py @@ -0,0 +1,68 @@ +import unittest +from game.quarry_rush.ability.landmine_active_ability import LandmineActiveAbility +from game.utils.vector import Vector + + +class TestLandmineActiveAbility(unittest.TestCase): + """ + This is class that tests the Landmine Active Ability + """ + + # set up + def setUp(self) -> None: + self.landmine_active_ability: LandmineActiveAbility = LandmineActiveAbility() + + # test: cooldown + def test_cooldown(self): + self.landmine_active_ability.cooldown = 1 + self.assertEqual(self.landmine_active_ability.cooldown, 1) + + # fail test: cooldown CANT be null + def test_cooldown_fail_null(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.cooldown = None + self.assertEqual(str(e.exception), 'LandmineActiveAbility.cooldown must be an int') + + # fail test: cooldown cant be anything else + def test_cooldown_fail_str(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.cooldown = "" + self.assertEqual(str(e.exception), 'LandmineActiveAbility.cooldown must be an int') + + # fail test: cooldown cannot be negative + def test_cooldown_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.cooldown = -1 + self.assertEqual(str(e.exception), 'LandmineActiveAbility.cooldown cannot be negative') + + # test: fuse + def test_fuse(self): + self.fuse = 1 + self.landmine_active_ability.fuse = 1 + self.assertEqual(self.landmine_active_ability.fuse, self.fuse) + + # fail test: fuse CANT be null + def test_fuse_fail_null(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.fuse = None + self.assertEqual(str(e.exception), 'LandmineActiveAbility.fuse must be an int') + + # fail test: fuse cannot be anything else + def test_fuse_fail_str(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.fuse = "" + self.assertEqual(str(e.exception), 'LandmineActiveAbility.fuse must be an int') + + # fail test: fuse cannot be negative + def test_fuse_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.landmine_active_ability.fuse = -1 + self.assertEqual(str(e.exception), 'LandmineActiveAbility.fuse cannot be negative') + + # test: json + def test_landmine_active_ability_json(self): + data: dict = self.landmine_active_ability.to_json() + landmine_active_ability: LandmineActiveAbility = LandmineActiveAbility().from_json(data) + self.assertEqual(self.landmine_active_ability.cooldown, landmine_active_ability.cooldown) + self.assertEqual(self.landmine_active_ability.fuse, landmine_active_ability.fuse) + self.assertEqual(self.landmine_active_ability.object_type, landmine_active_ability.object_type) diff --git a/game/test_suite/tests/test_mine_controller.py b/game/test_suite/tests/test_mine_controller.py index a8667350..7b9bc239 100644 --- a/game/test_suite/tests/test_mine_controller.py +++ b/game/test_suite/tests/test_mine_controller.py @@ -40,6 +40,17 @@ def test_mining(self): # self.assertTrue(isinstance(self.world.inventory_manager.get_inventory(self.avatar.company)[0], # Copium)) + def test_mining_full_inventory(self): + # fill inventory + [self.world.inventory_manager.give(Turite(), self.client.avatar.company) for x in range(50)] + + # attempt to mine + self.mine_controller.handle_actions(ActionType.MINE, self.client, self.world) + + # ensure the last slot is still Turite and not Copium + self.assertTrue(isinstance(self.world.inventory_manager.get_inventory(self.client.avatar.company)[49], + Turite)) + # def test_mining_fail(self): # pass # self.mine_controller.handle_actions(ActionType.MINE_ANCIENT_TECH, self.client, self.world) diff --git a/game/test_suite/tests/test_place_controller.py b/game/test_suite/tests/test_place_controller.py index 0a63c326..52f8a599 100644 --- a/game/test_suite/tests/test_place_controller.py +++ b/game/test_suite/tests/test_place_controller.py @@ -62,7 +62,7 @@ def test_placing_dynamite(self) -> None: self.assertEqual(placed_dyn.occupied_by, self.client.avatar) # double-check the ability cooldown reset - self.assertEqual(self.avatar.dynamite_active_ability.cooldown, 1) + self.assertEqual(self.avatar.dynamite_active_ability.cooldown, 4) def test_placing_landmine(self) -> None: self.movement_controller.handle_actions(ActionType.MOVE_DOWN, self.client, self.game_board) @@ -77,7 +77,7 @@ def test_placing_landmine(self) -> None: self.assertEqual(placed_landmine.occupied_by, self.client.avatar) # double-check the ability cooldown reset - self.assertEqual(self.avatar.landmine_active_ability.cooldown, 1) + self.assertEqual(self.avatar.landmine_active_ability.cooldown, 6) def test_placing_emp(self) -> None: self.avatar.buy_new_tech('EMPs') # unlock emps for testing @@ -93,7 +93,7 @@ def test_placing_emp(self) -> None: placed_emp: EMP = self.ore_station.occupied_by # returns the correct type; ignore warning self.assertEqual(placed_emp.occupied_by, self.client.avatar) - self.assertEqual(self.avatar.emp_active_ability.cooldown, 1) # double-check the ability cooldown reset + self.assertEqual(self.avatar.emp_active_ability.cooldown, 4) # double-check the ability cooldown reset # test that 2 dynamite aren't on the same tile def test_placing_multiple_dynamite(self): diff --git a/game/test_suite/tests/test_trap_defusal_active_ability.py b/game/test_suite/tests/test_trap_defusal_active_ability.py new file mode 100644 index 00000000..71da1b64 --- /dev/null +++ b/game/test_suite/tests/test_trap_defusal_active_ability.py @@ -0,0 +1,67 @@ +import unittest +from game.quarry_rush.ability.trap_defusal_active_ability import TrapDefusalActiveAbility + + +class TestTrapDefusalActiveAbility(unittest.TestCase): + """ + This is class that tests the Trap Defusal Active Ability + """ + + # set up + def setUp(self) -> None: + self.trap_defusal_active_ability: TrapDefusalActiveAbility = TrapDefusalActiveAbility() + + # test: cooldown + def test_cooldown(self): + self.trap_defusal_active_ability.cooldown = 1 + self.assertEqual(self.trap_defusal_active_ability.cooldown, 1) + + # fail test: cooldown CANT be null + def test_cooldown_fail_null(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.cooldown = None + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.cooldown must be an int') + + # fail test: cooldown cant be anything else + def test_cooldown_fail_str(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.cooldown = "" + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.cooldown must be an int') + + # fail test: cooldown cannot be negative + def test_cooldown_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.cooldown = -1 + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.cooldown cannot be negative') + + # test: fuse + def test_fuse(self): + self.fuse = 1 + self.trap_defusal_active_ability.fuse = 1 + self.assertEqual(self.trap_defusal_active_ability.fuse, self.fuse) + + # fail test: fuse CANT be null + def test_fuse_fail_null(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.fuse = None + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.fuse must be an int') + + # fail test: fuse cannot be anything else + def test_fuse_fail_str(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.fuse = "" + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.fuse must be an int') + + # fail test: fuse cannot be negative + def test_fuse_fail_negative(self): + with self.assertRaises(ValueError) as e: + self.trap_defusal_active_ability.fuse = -1 + self.assertEqual(str(e.exception), 'TrapDefusalActiveAbility.fuse cannot be negative') + + # test: json + def test_trap_defusal_active_ability_json(self): + data: dict = self.trap_defusal_active_ability.to_json() + trap_defusal_active_ability: TrapDefusalActiveAbility = TrapDefusalActiveAbility().from_json(data) + self.assertEqual(self.trap_defusal_active_ability.cooldown, trap_defusal_active_ability.cooldown) + self.assertEqual(self.trap_defusal_active_ability.fuse, trap_defusal_active_ability.fuse) + self.assertEqual(self.trap_defusal_active_ability.object_type, trap_defusal_active_ability.object_type)