fix: resolve merge conflicts between JSDF bases and East Asia adversary bases

Merge both feature sets: keep JSDF bases (gsdf/msdf/asdf branches) from
PR #77 and East Asia adversary bases (missile/nuclear branches) from main.
Union all branch types in tests and MaplibreViewer labels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
adust09
2026-03-17 01:10:19 +09:00
co-authored by Claude Opus 4.6
14 changed files with 1466 additions and 11 deletions
+34
View File
@@ -36,6 +36,24 @@ class TestEnrichCountry:
def test_invalid_hex_with_empty(self):
assert _enrich_country("ZZZZ", "") == ("Military Asset", "")
def test_russia_range(self):
assert _enrich_country("150000", "Unknown") == ("Russia", "VKS")
def test_russia_range_end(self):
assert _enrich_country("157FFF", "Unknown") == ("Russia", "VKS")
def test_australia_range(self):
assert _enrich_country("7C0000", "Unknown") == ("Australia", "RAAF")
def test_philippines_range(self):
assert _enrich_country("758000", "Unknown") == ("Philippines", "PAF")
def test_singapore_range(self):
assert _enrich_country("768000", "Unknown") == ("Singapore", "RSAF")
def test_north_korea_range(self):
assert _enrich_country("720000", "Unknown") == ("North Korea", "KPAF")
class TestClassifyMilitaryType:
@pytest.mark.parametrize("model,expected", [
@@ -52,6 +70,22 @@ class TestClassifyMilitaryType:
("H60", "heli"),
("K35", "tanker"),
("Boeing 737", "default"),
# Russian aircraft
("SU-27", "fighter"),
("SU-30", "fighter"),
("SU-35", "fighter"),
("SU-57", "fighter"),
("MiG-29", "fighter"),
("MiG-31", "fighter"),
("Tu-95", "bomber"),
("Tu-160", "bomber"),
("Tu-22", "bomber"),
("IL-76", "cargo"),
("AN-124", "cargo"),
("AN-12", "cargo"),
("A-50", "recon"),
("Tu-214R", "recon"),
("IL-20", "recon"),
])
def test_classification(self, model: str, expected: str):
assert _classify_military_type(model) == expected
+12 -1
View File
@@ -35,11 +35,22 @@ class TestMilitaryBasesData:
assert -180 <= entry["lng"] <= 180, f"{entry['name']} has invalid lng"
def test_branch_values_are_known(self):
known_branches = {"air_force", "navy", "marines", "army", "gsdf", "msdf", "asdf"}
known_branches = {"air_force", "navy", "marines", "army", "gsdf", "msdf", "asdf", "missile", "nuclear"}
raw = json.loads(BASES_PATH.read_text(encoding="utf-8"))
for entry in raw:
assert entry["branch"] in known_branches, f"{entry['name']} has unknown branch: {entry['branch']}"
def test_adversary_bases_present(self):
raw = json.loads(BASES_PATH.read_text(encoding="utf-8"))
countries = {entry["country"] for entry in raw}
for expected in ("China", "Russia", "North Korea", "Taiwan"):
assert expected in countries, f"Missing bases for {expected}"
def test_no_duplicate_names(self):
raw = json.loads(BASES_PATH.read_text(encoding="utf-8"))
names = [entry["name"] for entry in raw]
assert len(names) == len(set(names)), "Duplicate base names found"
class TestFetchMilitaryBases:
"""Test the fetcher populates latest_data correctly."""
+49 -1
View File
@@ -72,6 +72,53 @@ class TestResolveCoords:
result = _resolve_coords("visit the uk soon")
assert result == (55.378, -3.435)
# -- New East Asia island/strait keywords ------------------------------------
def test_pratas(self):
assert _resolve_coords("china patrols near pratas islands") == (20.71, 116.72)
def test_dongsha(self):
assert _resolve_coords("dongsha atoll tensions") == (20.71, 116.72)
def test_kinmen(self):
assert _resolve_coords("artillery drill near kinmen") == (24.45, 118.38)
def test_matsu(self):
assert _resolve_coords("matsu island cable cut") == (26.16, 119.94)
def test_scarborough(self):
assert _resolve_coords("scarborough shoal standoff") == (15.14, 117.77)
def test_paracel(self):
assert _resolve_coords("paracel islands dispute") == (16.50, 112.00)
def test_spratly(self):
assert _resolve_coords("spratly island reclamation") == (10.00, 114.00)
def test_miyako_strait(self):
assert _resolve_coords("PLAN warships transit miyako strait") == (24.78, 125.30)
def test_bashi_channel(self):
assert _resolve_coords("submarine detected in bashi channel") == (21.00, 121.50)
def test_luzon_strait(self):
assert _resolve_coords("luzon strait patrol") == (20.50, 121.50)
def test_dmz(self):
assert _resolve_coords("tension at the dmz border") == (38.00, 127.00)
def test_yalu(self):
assert _resolve_coords("troops near yalu river") == (40.00, 124.40)
def test_yongbyon(self):
assert _resolve_coords("activity at yongbyon reactor") == (39.80, 125.76)
def test_wonsan(self):
assert _resolve_coords("missile launch from wonsan") == (39.18, 127.48)
def test_busan(self):
assert _resolve_coords("naval exercise near busan port") == (35.18, 129.07)
# -- No match --------------------------------------------------------------
def test_no_match_returns_none(self):
@@ -98,5 +145,6 @@ class TestFeedConfig:
def test_new_east_asia_feeds_present(self):
names = {f["name"] for f in DEFAULT_FEEDS}
expected = {"FocusTaiwan", "Kyodo", "SCMP", "The Diplomat", "Stars and Stripes"}
expected = {"FocusTaiwan", "Kyodo", "SCMP", "The Diplomat", "Stars and Stripes",
"Yonhap", "Nikkei Asia", "Taipei Times", "Asia Times", "Defense News", "Japan Times"}
assert expected.issubset(names)