import fractions import typing import unittest from elite_engineering import materials class TradeCalculationTests(unittest.TestCase): def format_ratio(self, ratio: typing.Optional[fractions.Fraction]) -> str: if not ratio: return "-" return "{} → {}".format(ratio.numerator, ratio.denominator) def test_same_category_exchange(self) -> None: expected = [ ["1 → 1", "1 → 3", "1 → 9", "1 → 27", "1 → 81"], ["6 → 1", "1 → 1", "1 → 3", "1 → 9", "1 → 27"], ["36 → 1", "6 → 1", "1 → 1", "1 → 3", "1 → 9"], ["216 → 1", "36 → 1", "6 → 1", "1 → 1", "1 → 3"], ["-", "216 → 1", "36 → 1", "6 → 1", "1 → 1"], ] actual = [ [ self.format_ratio( materials.Material( "name", materials.MaterialType.raw, "category", grade_in ).trade_ratio( materials.Material( "name", materials.MaterialType.raw, "category", grade_out ) ) ) for grade_in in [1, 2, 3, 4, 5] ] for grade_out in [1, 2, 3, 4, 5] ] self.assertEqual(expected, actual) def test_different_category_exchange(self) -> None: expected = [ ["6 → 1", "2 → 1", "2 → 3", "2 → 9", "2 → 27"], ["36 → 1", "6 → 1", "2 → 1", "2 → 3", "2 → 9"], ["216 → 1", "36 → 1", "6 → 1", "2 → 1", "2 → 3"], ["-", "216 → 1", "36 → 1", "6 → 1", "2 → 1"], ["-", "-", "216 → 1", "36 → 1", "6 → 1"], ] actual = [ [ self.format_ratio( materials.Material( "name", materials.MaterialType.raw, "category", grade_in ).trade_ratio( materials.Material( "name", materials.MaterialType.raw, "other", grade_out ) ) ) for grade_in in [1, 2, 3, 4, 5] ] for grade_out in [1, 2, 3, 4, 5] ] self.assertEqual(expected, actual) def test_different_type_exchange(self) -> None: expected = [ ["-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-"], ] actual = [ [ self.format_ratio( materials.Material( "name", materials.MaterialType.raw, "category", grade_in ).trade_ratio( materials.Material( "name", materials.MaterialType.encoded, "other", grade_out ) ) ) for grade_in in [1, 2, 3, 4, 5] ] for grade_out in [1, 2, 3, 4, 5] ] self.assertEqual(expected, actual) class InventoryTests(unittest.TestCase): def test_create_empty_inventory(self) -> None: inventory = materials.Inventory() self.assertEqual(set(inventory.keys()), set(materials.materials.keys())) def test_create_populated_inventory(self) -> None: inventory = materials.Inventory({"Carbon": 5, "Shield Emitters": 3}) self.assertEqual(5, inventory["Carbon"]) self.assertEqual(3, inventory["Shield Emitters"]) self.assertEqual(8, sum(inventory.values())) def test_create_inventory_with_invalid_materials(self) -> None: with self.assertRaises(KeyError) as exc: materials.Inventory({"Carbon": 5, "Pizza": 12}) self.assertEqual(exc.exception.args, ("Pizza",)) def test_create_inventory_with_invalid_quantities(self) -> None: with self.assertRaises(ValueError) as exc: materials.Inventory({"Carbon": -5}) self.assertEqual(exc.exception.args, (-5,)) def test_inventory_has_materials(self) -> None: inventory = materials.Inventory({"Carbon": 5, "Shield Emitters": 3}) self.assertTrue(inventory.has({"Carbon": 1, "Shield Emitters": 3})) def test_inventory_lacks_materials(self) -> None: inventory = materials.Inventory({"Carbon": 5, "Shield Emitters": 3}) self.assertTrue(not inventory.has({"Nickel": 1})) self.assertTrue(not inventory.has({"Carbon": 6, "Shield Emitters": 3})) def test_inventory_has_raises_on_invalid_materials(self) -> None: inventory = materials.Inventory() with self.assertRaises(KeyError) as exc: inventory.has({"Carbon": 5, "Pizza": 12}) self.assertEqual(exc.exception.args, ("Pizza",)) def test_inventory_addition(self) -> None: a = materials.Inventory({"Carbon": 5, "Shield Emitters": 3}) b = materials.Inventory({"Iron": 2, "Shield Emitters": 3}) expected = materials.Inventory({"Carbon": 5, "Iron": 2, "Shield Emitters": 6}) self.assertEqual(expected, a + b) def test_inventory_subtraction(self) -> None: a = materials.Inventory({"Carbon": 5, "Iron": 2, "Shield Emitters": 6}) b = materials.Inventory({"Carbon": 5, "Shield Emitters": 3}) expected = materials.Inventory({"Iron": 2, "Shield Emitters": 3}) self.assertEqual(expected, a - b) def test_inventory_subtraction_cannot_result_in_negative_quantities(self) -> None: a = materials.Inventory({"Carbon": 5, "Iron": 2, "Shield Emitters": 6}) b = materials.Inventory({"Carbon": 6, "Shield Emitters": 3}) with self.assertRaises(ValueError) as exc: a - b self.assertEqual(exc.exception.args, (-1,))