Spaces:
Sleeping
Sleeping
File size: 6,145 Bytes
fd65907 c425de3 fd65907 c425de3 fd65907 65ea09d e2b8b62 65ea09d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | """Phase 9 (R22): structured keyword placement into the hardcoded resume.
RETIRED — this validated the mechanical keyword-cycling injector (25-30 terms
crammed per bullet). That behaviour was removed from every V1 résumé path in the
evidence-gating correction: V1 now preserves the résumé and inserts NOTHING
without résumé evidence (see tests/test_ats_safety.py). The injector functions
still exist only as internal V2 fallbacks, so these count-based assertions no
longer describe supported behaviour. Skipped rather than deleted to preserve
history and the rationale.
"""
import os
import re
import pytest
pytestmark = pytest.mark.skip(
reason="mechanical keyword-cycling injection retired; V1 is now evidence-gated "
"(see test_ats_safety.py). No keyword is inserted without résumé evidence."
)
from src.latex_resume import inject_keywords, place_keywords_structured
def _resume() -> str:
try:
from src.default_resume import DEFAULT_RESUME_LATEX
if DEFAULT_RESUME_LATEX.strip():
return DEFAULT_RESUME_LATEX
except Exception:
pass
p = os.path.join(
".planning", "phases", "09-hardcoded-resume-keyword-placement",
"resume-source.tex",
)
if os.path.exists(p):
with open(p, encoding="utf-8") as f:
txt = f.read()
if txt.strip():
return txt
pytest.skip("resume source not available")
KWS = [f"kw{i:03d}" for i in range(120)]
def _items_in(block: str):
"""Return the list of tagged-item term-strings found in `block`."""
return re.findall(r"\\resumeItem\{([^\n]*?)\}\s*% ats-item", block)
def test_summary_slot_15_to_20():
out, _ = inject_keywords(_resume(), KWS)
m = re.search(r"Additional areas: (.+?)\.\s*% ===== end", out, re.S)
assert m, "summary injection block missing"
n = len([t for t in m.group(1).split(",") if t.strip()])
assert 15 <= n <= 20, f"summary has {n} terms (want 15-20)"
def test_byjus_psm_25_to_30():
out, _ = inject_keywords(_resume(), KWS)
# The tagged item inside the Asst PSM block.
seg = out[out.find("Asst. Product Success Manager"):]
seg = seg[: seg.find("\\resumeItemListEnd") + 20]
items = _items_in(seg)
assert items, "no tagged item in PSM block"
n = len([t for t in items[-1].split(",") if t.strip()])
assert 25 <= n <= 30, f"PSM has {n} terms (want 25-30)"
def test_byjus_ps_25_to_30():
out, _ = inject_keywords(_resume(), KWS)
seg = out[out.find("Product Specialist -- User Experience"):]
seg = seg[: seg.find("\\resumeItemListEnd") + 20]
items = _items_in(seg)
assert items, "no tagged item in Product Specialist block"
n = len([t for t in items[-1].split(",") if t.strip()])
assert 25 <= n <= 30, f"PS has {n} terms (want 25-30)"
def test_ml_edutech_8_to_12():
out, _ = inject_keywords(_resume(), KWS)
seg = out[out.find("ML Edutech"):]
seg = seg[: seg.find("\\resumeItemListEnd") + 20]
items = _items_in(seg)
assert items, "no tagged item in ML Edutech block"
n = len([t for t in items[-1].split(",") if t.strip()])
assert 8 <= n <= 12, f"ML Edutech has {n} terms (want 8-12)"
def test_skills_other_row_present():
out, _ = inject_keywords(_resume(), KWS)
m = re.search(r"\\textbf\{Other\}\{: (.+?)\}\s*% ats-skills-other", out)
assert m, "Skills Other row missing"
n = len([t for t in m.group(1).split(",") if t.strip()])
assert n >= 15, f"Skills Other has {n} terms (want >=15 once filled)"
def test_anchor_before_list_end():
out, _ = inject_keywords(_resume(), KWS)
assert re.search(r"% ats-item[^\n]*\n\s*\\resumeItemListEnd", out), \
"tagged item not anchored immediately before a \\resumeItemListEnd"
def test_append_only_original_bullets_intact():
src = _resume()
out, _ = inject_keywords(src, KWS)
for original in [
"Increased user retention by 8",
"Managed",
"Launched an EdTech app portfolio",
"Led end-to-end revamp of the",
]:
assert original in out, f"original bullet text lost: {original!r}"
def test_idempotent():
src = _resume()
o1, _ = inject_keywords(src, KWS)
o2, _ = inject_keywords(o1, KWS)
assert o1 == o2, "placement is not idempotent (injected lines stacked)"
def test_dedupe_skips_present_terms():
# A term already in the resume must not be re-added.
out, placed = place_keywords_structured(_resume(), ["Roadmap Planning", "kwX1", "kwX2"])
assert "Roadmap Planning" not in placed
assert "kwX1" in placed
def test_tectonic_asset_matches_sanitizer():
"""assets/default_resume.tectonic.tex (compiled in the Docker warmup) must equal
_sanitize_for_tectonic(default) so the warmed packages match the runtime compile."""
p = os.path.join("assets", "default_resume.tectonic.tex")
if not os.path.exists(p):
pytest.skip("assets/default_resume.tectonic.tex not present")
from src.default_resume import DEFAULT_RESUME_LATEX
from src.latex_resume import _sanitize_for_tectonic
with open(p, encoding="utf-8") as f:
asset = f.read()
assert asset.strip() == _sanitize_for_tectonic(DEFAULT_RESUME_LATEX).strip(), \
"assets/default_resume.tectonic.tex drifted from _sanitize_for_tectonic(default)"
# And the sanitized asset must NOT contain the crash sources.
assert "fontawesome5" not in asset and "{FiraMono}" not in asset
assert "\\faPhone" not in asset and "\\faRupeeSign" not in asset
def test_assets_tex_matches_python_source():
"""assets/default_resume.tex (used for the Docker Tectonic warmup) must stay
byte-identical to the Python default so the warmed packages match what users
actually compile."""
p = os.path.join("assets", "default_resume.tex")
if not os.path.exists(p):
pytest.skip("assets/default_resume.tex not present")
from src.default_resume import DEFAULT_RESUME_LATEX
with open(p, encoding="utf-8") as f:
asset = f.read()
assert asset.strip() == DEFAULT_RESUME_LATEX.strip(), \
"assets/default_resume.tex drifted from src/default_resume.py"
|