Files
ai-job-search/tests/test_convert_salary_excel.py
T
Erik Pastor RiosandClaude Opus 4.8 a278ad7a50 refactor(salary): make compound-word matching locale-agnostic (#94)
* refactor(salary): make compound-word matching locale-agnostic

The Excel column detector hardcoded a DANISH_COMPOUND_PATTERNS set inside
header_matches(), so the compound-word matching that helps Danish headers
(e.g. "lønindeks") was baked into the algorithm by name and unavailable to
any other locale without editing the source.

Rename it to COMPOUND_PATTERNS and pass it as a parameter (default
unchanged, so the Danish demonstration data behaves identically). A
different-locale spreadsheet can now supply its own compound tokens via
header_matches(..., compound_patterns=...). Add a test covering both the
preserved default and the parameterized path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(salary): drop unused compound_patterns parameter

Per review: keep the DANISH_COMPOUND_PATTERNS -> COMPOUND_PATTERNS
rename (universal template naming, defaults still Danish), but remove
the compound_patterns= parameter. No caller passes a custom set, and a
fork adapting another locale edits the module-level constant either way,
so parameterizing it is speculative generality per CONTRIBUTING.md.

header_matches() now reads COMPOUND_PATTERNS directly. Test updated to
verify compound-vs-whole-token matching against the constant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 08:06:05 +02:00

83 lines
3.0 KiB
Python

import unittest
from types import SimpleNamespace
from tools.convert_salary_excel import (
INDEX_PATTERNS,
detect_column_type,
header_matches,
parse_sheet,
)
class FakeWorksheet:
title = "Sheet1"
def __init__(self, rows):
self.rows = rows
def iter_rows(self, min_row=1, max_row=None, values_only=False):
rows = self.rows[min_row - 1:max_row]
for row in rows:
if values_only:
yield row
else:
yield [SimpleNamespace(value=value) for value in row]
def __getitem__(self, row_number):
return [SimpleNamespace(value=value) for value in self.rows[row_number - 1]]
class DetectColumnTypeTests(unittest.TestCase):
def test_index_headers_are_not_misclassified_as_count(self):
for header in ("Index", "Salary Index", "Engineering Index", "Median salary"):
with self.subTest(header=header):
self.assertEqual(detect_column_type(header), "index")
def test_single_letter_n_only_matches_as_a_token(self):
self.assertEqual(detect_column_type("Employee n"), "count")
self.assertEqual(detect_column_type("Engineering"), None)
def test_count_headers_still_match_common_labels(self):
for header in ("Count", "Engineering Count", "Antal medarbejdere"):
with self.subTest(header=header):
self.assertEqual(detect_column_type(header), "count")
def test_count_inside_word_does_not_make_count_header(self):
self.assertIsNone(detect_column_type("Accounting Total"))
self.assertEqual(detect_column_type("Accounting Index"), "index")
def test_danish_compound_headers_still_match(self):
self.assertEqual(detect_column_type("Lønindeks"), "index")
def test_compound_patterns_match_as_substring_but_others_do_not(self):
# A compound token (Danish "løn") matches inside a glued header word.
self.assertTrue(header_matches("lønindeks", INDEX_PATTERNS))
# A pattern that is not a compound token ("salary") only matches as a
# whole token, so it must not match inside an unrelated glued word.
self.assertFalse(header_matches("salaryindex", INDEX_PATTERNS))
self.assertTrue(header_matches("salary index", INDEX_PATTERNS))
def test_parse_sheet_preserves_category_name_with_letter_n(self):
ws = FakeWorksheet([
("Company", "Engineering Count", "Engineering Index"),
("Example Corp", 12, 105.5),
])
companies = parse_sheet(ws)
self.assertEqual(companies[0]["categories"]["engineering"], {"count": 12, "index": 105.5})
def test_parse_sheet_groups_accounting_count_index_pair(self):
ws = FakeWorksheet([
("Company", "Accounting Count", "Accounting Index"),
("Example Corp", 12, 105.5),
])
companies = parse_sheet(ws)
self.assertEqual(companies[0]["categories"]["accounting"], {"count": 12, "index": 105.5})
if __name__ == "__main__":
unittest.main()