mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 00:26:26 +00:00
fix(salary-tools): decide number locale by last separator, pair compound headers
Review findings F7 and F8 (2026-08-19):
- parse_numeric_cell's both-separators branch always assumed European
locale, silently turning a US "1,234.56" into 1.23456 - a 1000x
corruption written to salary_data.json with no warning. The separator
that appears last is now treated as the decimal separator, which also
makes multi-group values ("1,234,567.89") parse instead of raising a
raw float error. Single-separator ambiguity guards are unchanged.
- strip_type_patterns stripped only whole tokens, so the compound header
"Lønindeks alle" kept its type word and could never pair with "Antal
alle" - failing exactly for the compound-word locale COMPOUND_PATTERNS
exists to support. It now also strips compound patterns as substrings,
mirroring header_matches.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7aba0b4a9d
commit
1c19f6c45f
@@ -5,6 +5,7 @@ from tools.convert_salary_excel import (
|
||||
INDEX_PATTERNS,
|
||||
detect_column_type,
|
||||
header_matches,
|
||||
parse_numeric_cell,
|
||||
parse_sheet,
|
||||
)
|
||||
|
||||
@@ -288,3 +289,54 @@ class DetectColumnTypeTests(unittest.TestCase):
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
class ParseNumericCellLocaleTests(unittest.TestCase):
|
||||
# The separator that appears LAST is the decimal separator. Assuming
|
||||
# European ("." thousands, "," decimal) for every both-separator string
|
||||
# turned a US "1,234.56" into 1.23456 - a silent 1000x corruption that
|
||||
# flowed into salary_data.json and negotiation advice.
|
||||
|
||||
def test_us_thousands_and_decimal_string(self):
|
||||
self.assertEqual(parse_numeric_cell("1,234.56"), 1234.56)
|
||||
|
||||
def test_us_multiple_thousands_groups(self):
|
||||
self.assertEqual(parse_numeric_cell("1,234,567.89"), 1234567.89)
|
||||
|
||||
def test_european_thousands_and_decimal_string(self):
|
||||
self.assertEqual(parse_numeric_cell("1.234,56"), 1234.56)
|
||||
|
||||
def test_european_multiple_thousands_groups(self):
|
||||
self.assertEqual(parse_numeric_cell("1.234.567,89"), 1234567.89)
|
||||
|
||||
|
||||
class CompoundCategoryPairingTests(unittest.TestCase):
|
||||
def test_parse_sheet_pairs_danish_compound_index_with_count(self):
|
||||
# "Lønindeks alle" is *detected* as an index column via
|
||||
# COMPOUND_PATTERNS, but the derived category name must also lose the
|
||||
# compound word or it can never pair with "Antal alle" ("alle" vs
|
||||
# "lønindeks alle") - exactly the locale the compound support exists for.
|
||||
ws = FakeWorksheet([
|
||||
("Firma", "Antal alle", "Lønindeks alle"),
|
||||
("Example Corp", 12, 118.0),
|
||||
])
|
||||
|
||||
companies = parse_sheet(ws)
|
||||
|
||||
self.assertEqual(
|
||||
companies[0]["categories"]["alle"],
|
||||
{"count": 12, "index": 118.0},
|
||||
)
|
||||
|
||||
def test_parse_sheet_sheet_level_us_locale_value(self):
|
||||
ws = FakeWorksheet([
|
||||
("Company", "Salary Index"),
|
||||
("Example Corp", "1,234.56"),
|
||||
])
|
||||
|
||||
companies = parse_sheet(ws)
|
||||
|
||||
self.assertEqual(
|
||||
companies[0]["categories"]["salary_index"],
|
||||
{"index": 1234.56},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user