"""Phase 1 — skill normalization + coverage-aware (floor-free) overlap.""" from app.engine import skills as S def test_synonym_and_fold(): assert S.norm("React.js") == "react" assert S.norm("K8s") == "kubernetes" assert S.norm(" ML ") == "machine learning" c = S.canon(["ML", "Python", "react.js"]) assert {"machine learning", "python", "react"} <= c def test_overlap_is_floor_free(): assert S.overlap([], ["python"]) is None # empty user → absent (NOT 0 or 60) assert S.overlap(["python"], []) is None # empty job → absent o = S.overlap(["python", "sql", "django"], ["Python", "Django", "AWS"]) assert o is not None and 0.0 < o["score"] <= 1.0 assert "python" in o["matched"] and "amazon web services" in o["missing"] def test_dims_levels(): rows = {r["name"]: r["level"] for r in S.dims(["product management"], ["Product Management", "SQL"], k=2)} assert rows["Product Management"] == "Strong" assert rows["Sql"] == "Light"