test: add coverage for match_score and search_company (#106) (#109)

This commit is contained in:
Sai Sridhar Tarra
2026-07-10 08:05:02 +02:00
committed by GitHub
parent 30e8b44759
commit 44fa00c8c6
+152 -1
View File
@@ -1,8 +1,14 @@
"""Tests for salary_lookup.py — format_entry, match_score, and search_company."""
import unittest import unittest
from salary_lookup import format_entry, search_company from salary_lookup import format_entry, match_score, search_company
# ---------------------------------------------------------------------------
# format_entry tests (from #75 / #98)
# ---------------------------------------------------------------------------
class FormatEntryTests(unittest.TestCase): class FormatEntryTests(unittest.TestCase):
def test_zero_count_is_displayed_as_zero(self): def test_zero_count_is_displayed_as_zero(self):
entry = { entry = {
@@ -67,6 +73,77 @@ class FormatEntryTests(unittest.TestCase):
self.assertIn("+12.5%", rendered) self.assertIn("+12.5%", rendered)
# ---------------------------------------------------------------------------
# match_score tests (from #106)
# ---------------------------------------------------------------------------
class TestMatchScoreExactMatch(unittest.TestCase):
def test_exact_match_returns_100(self):
self.assertEqual(match_score("Novo Nordisk", "Novo Nordisk"), 100)
def test_exact_match_case_insensitive(self):
self.assertEqual(match_score("NOVO NORDISK", "Novo Nordisk"), 100)
def test_exact_match_after_suffix_stripping(self):
self.assertEqual(match_score("Mærsk", "Mærsk A/S"), 100)
class TestMatchScoreSubstring(unittest.TestCase):
def test_query_contained_in_entry_gives_high_score(self):
score = match_score("Carlsberg", "Carlsberg Danmark A/S")
self.assertGreaterEqual(score, 80)
def test_entry_contained_in_query_gives_high_score(self):
score = match_score("Carlsberg Danmark", "Carlsberg")
self.assertGreaterEqual(score, 80)
class TestMatchScoreShortQuery(unittest.TestCase):
def test_short_query_no_word_overlap_returns_zero(self):
score = match_score("ab", "Something Unrelated Company")
self.assertEqual(score, 0)
def test_short_query_with_word_overlap_scores(self):
score = match_score("IBM", "IBM Corporation")
self.assertGreater(score, 0)
class TestMatchScoreAnglicize(unittest.TestCase):
def test_oe_variant_matches_o_with_slash(self):
score = match_score("Maersk", "Mærsk A/S")
self.assertGreater(score, 0)
def test_aa_variant_matches_aa(self):
self.assertEqual(match_score("Aarsleff", "Aarsleff"), 100)
def test_danish_characters_roundtrip(self):
score = match_score("Maersk", "Mærsk A/S")
self.assertGreater(score, 0)
class TestMatchScoreNoOverlap(unittest.TestCase):
def test_completely_unrelated_names_return_zero(self):
self.assertEqual(match_score("Apple", "Vestas Wind Systems"), 0)
def test_empty_query_returns_zero(self):
self.assertEqual(match_score("", "Novo Nordisk"), 0)
def test_empty_entry_returns_zero(self):
self.assertEqual(match_score("Novo Nordisk", ""), 0)
# ---------------------------------------------------------------------------
# search_company tests (from #75 / #98 and #106)
# ---------------------------------------------------------------------------
def _make_data(*entries):
return {"companies": list(entries)}
def _entry(company, city=""):
return {"company": company, "city": city}
class SearchCompanyTests(unittest.TestCase): class SearchCompanyTests(unittest.TestCase):
def test_search_company_with_none_city(self): def test_search_company_with_none_city(self):
data = { data = {
@@ -81,5 +158,79 @@ class SearchCompanyTests(unittest.TestCase):
self.assertEqual(results, []) self.assertEqual(results, [])
class TestSearchCompanyBasicMatch(unittest.TestCase):
def test_exact_name_returns_match(self):
data = _make_data(_entry("Novo Nordisk", "Bagsværd"))
results = search_company(data, "Novo Nordisk")
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["company"], "Novo Nordisk")
def test_no_match_returns_empty_list(self):
data = _make_data(_entry("Vestas Wind Systems", "Aarhus"))
results = search_company(data, "Apple")
self.assertEqual(results, [])
def test_multiple_candidates_all_returned(self):
data = _make_data(
_entry("Carlsberg A/S", "Copenhagen"),
_entry("Carlsberg Danmark", "Fredericia"),
_entry("Unrelated Corp", "Odense"),
)
results = search_company(data, "Carlsberg")
companies = [r["company"] for r in results]
self.assertIn("Carlsberg A/S", companies)
self.assertIn("Carlsberg Danmark", companies)
self.assertNotIn("Unrelated Corp", companies)
class TestSearchCompanyCityFilter(unittest.TestCase):
def test_matching_city_is_included(self):
data = _make_data(
_entry("Novo Nordisk", "Bagsværd"),
_entry("Novo Nordisk", "Aarhus"),
)
results = search_company(data, "Novo Nordisk", city="Aarhus")
self.assertEqual(len(results), 1)
self.assertEqual(results[0]["city"], "Aarhus")
def test_non_matching_city_is_excluded(self):
data = _make_data(_entry("Novo Nordisk", "Bagsværd"))
results = search_company(data, "Novo Nordisk", city="Odense")
self.assertEqual(results, [])
def test_no_city_filter_returns_all_cities(self):
data = _make_data(
_entry("Novo Nordisk", "Bagsværd"),
_entry("Novo Nordisk", "Aarhus"),
)
results = search_company(data, "Novo Nordisk")
self.assertEqual(len(results), 2)
def test_city_filter_case_insensitive(self):
data = _make_data(_entry("Novo Nordisk", "København"))
results = search_company(data, "Novo Nordisk", city="københavn")
self.assertEqual(len(results), 1)
def test_anglicized_city_matches_danish_city(self):
data = _make_data(_entry("Novo Nordisk", "København"))
results = search_company(data, "Novo Nordisk", city="kobenhavn")
self.assertEqual(len(results), 1)
class TestSearchCompanyScoreThreshold(unittest.TestCase):
def test_low_score_matches_excluded(self):
data = _make_data(_entry("Novo Nordisk", "Bagsværd"))
results = search_company(data, "xyz")
self.assertEqual(results, [])
def test_results_sorted_by_relevance_descending(self):
data = _make_data(
_entry("Novo Nordisk International", "Bagsværd"),
_entry("Novo Nordisk", "Bagsværd"),
)
results = search_company(data, "Novo Nordisk")
self.assertEqual(results[0]["company"], "Novo Nordisk")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()