126 lines
No EOL
4.1 KiB
Python
126 lines
No EOL
4.1 KiB
Python
"""Tests for similarity helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from matching.similarity import (
|
|
normalize_employer,
|
|
title_score,
|
|
employer_match,
|
|
desc_score,
|
|
)
|
|
|
|
|
|
class TestNormalizeEmployer:
|
|
def test_simple_lowercase(self):
|
|
assert normalize_employer("Acme") == "acme"
|
|
|
|
def test_strips_swedish_ab(self):
|
|
assert normalize_employer("Acme AB") == "acme"
|
|
|
|
def test_strips_aktiebolag(self):
|
|
assert normalize_employer("Acme Aktiebolag") == "acme"
|
|
|
|
def test_strips_consulting_suffix(self):
|
|
assert normalize_employer("Nordic IT Consulting AB") == "nordic it"
|
|
|
|
def test_strips_corp_suffix(self):
|
|
assert normalize_employer("Globex Corp.") == "globex"
|
|
|
|
def test_strips_ltd_suffix(self):
|
|
assert normalize_employer("Foo Ltd") == "foo"
|
|
|
|
def test_strips_recruitment_suffix(self):
|
|
assert normalize_employer("Acme Recruitment Group") == "acme"
|
|
|
|
def test_strips_multiple_suffixes(self):
|
|
# "Consulting AB" should strip both "AB" then "Consulting"
|
|
assert normalize_employer("Nordic Consulting AB") == "nordic"
|
|
|
|
def test_removes_punctuation(self):
|
|
assert normalize_employer("Acme, Inc.") == "acme"
|
|
|
|
def test_empty_string(self):
|
|
assert normalize_employer("") == ""
|
|
|
|
def test_whitespace_only(self):
|
|
assert normalize_employer(" ") == ""
|
|
|
|
def test_preserves_core_name_with_special_chars(self):
|
|
result = normalize_employer("Café Nu AB")
|
|
assert "café" in result or "cafe" in result
|
|
|
|
def test_dots_in_name_preserved(self):
|
|
# Punctuation (except & which gets stripped) is removed; H&M -> h m
|
|
result = normalize_employer("H&M AB")
|
|
assert result == "h m"
|
|
|
|
|
|
class TestTitleScore:
|
|
def test_identical_titles(self):
|
|
assert title_score("Senior Python Developer", "Senior Python Developer") == 100.0
|
|
|
|
def test_similar_titles_high_score(self):
|
|
score = title_score("Python Developer", "Senior Python Developer")
|
|
assert score >= 85.0
|
|
|
|
def test_different_titles_low_score(self):
|
|
score = title_score("Python Developer", "Frontend Designer")
|
|
assert score < 50.0
|
|
|
|
def test_empty_title(self):
|
|
assert title_score("", "Something") == 0.0
|
|
|
|
def test_both_empty(self):
|
|
assert title_score("", "") == 0.0
|
|
|
|
def test_order_independent(self):
|
|
# token_set_ratio is order-independent
|
|
a = "Senior Python Developer"
|
|
b = "Developer Python Senior"
|
|
assert title_score(a, b) == 100.0
|
|
|
|
|
|
class TestEmployerMatch:
|
|
def test_same_name_matches(self):
|
|
assert employer_match("Acme AB", "Acme AB") is True
|
|
|
|
def test_suffix_variation_matches(self):
|
|
assert employer_match("Acme AB", "Acme") is True
|
|
|
|
def test_different_employers_no_match(self):
|
|
assert employer_match("Acme AB", "Globex AB") is False
|
|
|
|
def test_consulting_variations_match(self):
|
|
assert employer_match("Nordic IT Consulting AB", "Nordic IT") is True
|
|
|
|
def test_empty_no_match(self):
|
|
assert employer_match("", "") is False
|
|
|
|
def test_one_empty_no_match(self):
|
|
assert employer_match("Acme", "") is False
|
|
|
|
|
|
class TestDescScore:
|
|
def test_identical_descriptions(self):
|
|
desc = "We are looking for a Python developer with 5 years experience."
|
|
assert desc_score(desc, desc) == 100.0
|
|
|
|
def test_similar_descriptions_high(self):
|
|
a = "We are looking for a Python developer with 5 years experience."
|
|
b = "We are looking for a Python developer with 5 years experience in web."
|
|
assert desc_score(a, b) >= 80.0
|
|
|
|
def test_different_descriptions_low(self):
|
|
a = "We need a frontend developer skilled in React and CSS."
|
|
b = "Looking for a data scientist with Python and SQL expertise."
|
|
assert desc_score(a, b) < 50.0
|
|
|
|
def test_empty_desc(self):
|
|
assert desc_score("", "something") == 0.0
|
|
|
|
def test_truncation(self):
|
|
# Test that truncation to max_chars works.
|
|
long_a = "Python " * 1000
|
|
long_b = "Python " * 1000
|
|
score = desc_score(long_a, long_b, max_chars=100)
|
|
assert score == 100.0 |