Files
id5100/test_repeaters.py
2026-06-14 16:09:04 -04:00

81 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Unit tests for repeaters.py (pure: no network, no radio). `python3 -m unittest`."""
import unittest
import repeaters
class TestNormalizeCsv(unittest.TestCase):
ROW = {
"Output Freq": "147.300000", "Input Freq": "147.90000", "Offset": "+",
"Uplink Tone": "131.8", "Downlink Tone": "131.8", "Call": "W4ABC",
"Location": "Fairfax", "County": "Fairfax", "State": "Virginia",
"Modes": "FM ", "Digital Access": "",
}
def test_core_fields(self):
r = repeaters.normalize_csv(self.ROW, 7)
self.assertEqual(r["callsign"], "W4ABC")
self.assertAlmostEqual(r["output_mhz"], 147.300)
self.assertEqual(r["rank"], 7)
self.assertEqual(r["location"], "Fairfax, VA")
def test_offset_sign_and_magnitude(self):
r = repeaters.normalize_csv(self.ROW, 0)
self.assertEqual(r["duplex"], "+")
self.assertAlmostEqual(r["offset_mhz"], 0.600, places=4)
def test_negative_offset(self):
row = dict(self.ROW, **{"Input Freq": "146.700000", "Offset": "-"})
self.assertEqual(repeaters.normalize_csv(row, 0)["duplex"], "-")
def test_simplex(self):
row = dict(self.ROW, **{"Input Freq": "147.300000", "Offset": ""})
self.assertEqual(repeaters.normalize_csv(row, 0)["duplex"], "simplex")
def test_tone(self):
r = repeaters.normalize_csv(self.ROW, 0)
self.assertAlmostEqual(r["tone_hz"], 131.8)
self.assertEqual(r["tone_mode"], "ctcss")
def test_no_tone(self):
row = dict(self.ROW); row["Uplink Tone"] = ""
r = repeaters.normalize_csv(row, 0)
self.assertIsNone(r["tone_hz"])
self.assertEqual(r["tone_mode"], "none")
def test_pure_dstar_is_dv(self):
row = dict(self.ROW, **{"Modes": "DSTAR "})
self.assertEqual(repeaters.normalize_csv(row, 0)["mode"], "DV")
def test_fm_dstar_is_fm(self):
row = dict(self.ROW, **{"Modes": "FM DSTAR "})
self.assertEqual(repeaters.normalize_csv(row, 0)["mode"], "FM")
class TestSearch(unittest.TestCase):
RECS = [
{"callsign": "NEAR", "location": "Fairfax, VA", "mode": "FM", "rank": 0},
{"callsign": "MID", "location": "Bethesda, MD", "mode": "DV", "rank": 5},
{"callsign": "FAR", "location": "Norfolk, VA", "mode": "FM", "rank": 50},
]
def test_rank_order_preserved(self):
out = repeaters.search(self.RECS, "", 10)
self.assertEqual([r["callsign"] for r in out], ["NEAR", "MID", "FAR"])
def test_text_filter_callsign_and_location(self):
self.assertEqual(len(repeaters.search(self.RECS, "norfolk", 10)), 1)
self.assertEqual(repeaters.search(self.RECS, "far", 10)[0]["callsign"], "FAR")
def test_filter_is_case_insensitive(self):
self.assertEqual(repeaters.search(self.RECS, "BETHESDA", 10)[0]["callsign"], "MID")
def test_limit(self):
self.assertEqual(len(repeaters.search(self.RECS, "", 2)), 2)
class TestLoad(unittest.TestCase):
def test_missing_file_returns_empty(self):
self.assertEqual(repeaters.load("/no/such/file.json"), [])