import importlib.util from pathlib import Path spec = importlib.util.spec_from_file_location("runway", Path(__file__).resolve().parent.parent / "tools" / "runway.py") runway = importlib.util.module_from_spec(spec) spec.loader.exec_module(runway) STATE = { "storage": [ {"type": "STORE", "planet": "ZV-759c", "items": {"C": 6, "STL": 0}}, {"type": "STORE", "planet": "ZV-194a", "items": {"RAT": 30}}, # Nike's, must not leak into Deimos {"type": "SHIP_STORE", "name": "AVI-07JFB", "items": {"C": 39, "STL": 15}}, {"type": "SHIP_STORE", "name": "AVI-07JFC", "items": {"MCG": 205}}, # not inbound to Deimos in this fixture ], "ships": [ {"reg": "AVI-07JFB", "flight": {"destination": "Antares II (ZV-759) - Deimos (ZV-759c)"}}, {"reg": "AVI-07JFC", "flight": {"destination": "Antares III (ZV-194) - Nike (ZV-194a)"}}, {"reg": "AVI-IDLE", "flight": None}, ], } def test_inbound_ships_matches_destination_planet(): assert runway.inbound_ships(STATE, "ZV-759c") == ["AVI-07JFB"] assert runway.inbound_ships(STATE, "ZV-194a") == ["AVI-07JFC"] def test_inbound_ships_ignores_ships_with_no_flight(): assert "AVI-IDLE" not in runway.inbound_ships(STATE, "ZV-759c") def test_on_hand_scopes_store_to_the_right_planet(): have = runway.on_hand(STATE, "ZV-759c", ships=[]) assert have == {"C": 6, "STL": 0} # Nike's RAT must not appear here def test_on_hand_adds_named_ship_cargo(): have = runway.on_hand(STATE, "ZV-759c", ships=["AVI-07JFB"]) assert have == {"C": 45, "STL": 15} # 6+39, 0+15 def test_on_hand_with_inbound_ships_end_to_end(): ships = runway.inbound_ships(STATE, "ZV-759c") have = runway.on_hand(STATE, "ZV-759c", ships) assert have == {"C": 45, "STL": 15} # only JFB counted, not JFC (heading to Nike)