Spaces:
Sleeping
Sleeping
File size: 7,232 Bytes
0af6235 355c4d1 0af6235 355c4d1 0af6235 | 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 160 161 | #!/usr/bin/env python3
"""Regression for the live-test bugs (Phase 8 follow-up):
BUG A Tectonic was invoked with `--synctex 0` -> the `0` is consumed as the
INPUT and the real .tex becomes an "unexpected argument", so the PDF
never compiles. Fix: minimal `tectonic --outdir <dir> --keep-logs <tex>`.
BUG B content.js stripChrome() read textContent off a DETACHED clone, joining
adjacent elements with NO whitespace -> Frankenstein tokens like
"engineergreater hyderabad" / "managerzamp". Fix: insert separators.
BUG C A jobs LIST / search / recommendations page (title "Top job picks for
you") produced junk keywords and a 0% resume. Fix: detect + fail loudly.
Deterministic, ASCII-only, no network, no LaTeX engine required.
"""
import os
import re
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT)
_ok = True
def check(name, cond, detail=""):
global _ok
status = "PASS" if cond else "FAIL"
if not cond:
_ok = False
print(f" [{status}] {name}" + (f" {detail}" if detail else ""))
return cond
def read(rel):
with open(os.path.join(ROOT, rel), encoding="utf-8") as f:
return f.read()
print("=" * 70)
print("Phase 8 follow-up: extraction + LaTeX-compile bug fixes")
print("=" * 70)
# ββ BUG A: Tectonic command line βββββββββββββββββββββββββββββββββββββββββββββ
print("[A] Tectonic invocation is well-formed (no --synctex value trap)")
from src.latex_resume import _engine_commands
cmds = _engine_commands("tectonic", "/tmp/out/resume.tex", "/tmp/out")
cmd = cmds[0]
check("engine is tectonic", cmd[0] == "tectonic", " ".join(cmd))
check("no --synctex flag", "--synctex" not in cmd)
check("no bare numeric positional ('0')", "0" not in cmd)
check("input .tex is the final positional",
cmd[-1] == "/tmp/out/resume.tex", cmd[-1])
check("--outdir points at the out dir",
"--outdir" in cmd and cmd[cmd.index("--outdir") + 1] == "/tmp/out")
# ββ BUG B: stripChrome inserts whitespace separators βββββββββββββββββββββββββ
print("[B] content.js stripChrome separates tokens (no concatenation)")
content = read("extension/content.js")
check("inserts a separator text node between elements",
"createTextNode(' \\n')" in content)
check("reads textContent after inserting separators",
"clone.textContent" in content)
# ββ BUG C: non-job / listing-page detection ββββββββββββββββββββββββββββββββββ
print("[C] content.js rejects jobs-list / recommendation pages")
check("NON_JOB_TITLES table present", "NON_JOB_TITLES" in content)
check("'top job picks for you' is blacklisted",
"top job picks for you" in content.lower())
check("looksLikeListingJunk() exists", "looksLikeListingJunk" in content)
check("flags repeated 'easy apply' rows", "easy apply" in content.lower())
check("sets extraction_reason='not_a_job_posting'",
"not_a_job_posting" in content)
check("raises the min-JD-length gate to 80",
"length < 80" in content)
print("[C] popup.js surfaces the not-a-posting reason")
popup = read("extension/popup/popup.js")
check("popup handles not_a_job_posting", "not_a_job_posting" in popup)
# ββ Realistic LaTeX injection coverage (no compile needed) ββββββββββββββββββββ
print("[D] Realistic PM LaTeX + JD -> honest keyword coverage")
from src.latex_resume import optimize_latex_resume
SAMPLE_LATEX = r"""
\documentclass{article}
\begin{document}
\section*{Summary}
Product Manager with experience shipping B2B SaaS products, partnering with
engineering and design, and running discovery with customers.
\section*{Experience}
\textbf{Senior Product Manager} \\ Acme SaaS (2021--2024)
\begin{itemize}
\item Owned the product roadmap for a B2B analytics platform.
\item Ran A/B tests and user research to prioritize the backlog.
\item Partnered with engineering on go-to-market for two launches.
\end{itemize}
\end{document}
"""
JD = (
"We are hiring a Product Manager for our B2B SaaS platform. You will own the "
"product roadmap, define product strategy, run user research and discovery, "
"prioritize the backlog, partner with engineering and design, lead "
"go-to-market, run A/B testing and experimentation, define KPIs and metrics, "
"and work with stakeholders. Experience with agile, data analysis, SQL, "
"machine learning and generative AI product features is a plus. Strong "
"stakeholder management and roadmapping skills required."
)
report = optimize_latex_resume(
SAMPLE_LATEX, JD, maximum_ats_mode=True, confirmed_terms=[],
blocked_terms=[], compile_pdf=False, out_dir=None, job_title="pm",
)
pct = int(report.get("pct", 0) or 0)
injected = report.get("injected", [])
gated = report.get("gated", {}) or {}
blocked_injected = [t for t in injected
if "blocked" in str(gated.get(t, "")).lower()]
print(f" coverage pct = {pct}% injected = {len(injected)} terms")
check("coverage >= 85% on a well-matched PM JD (path can reach 90%+)",
pct >= 85, f"{pct}%")
check("no blocked/fabrication term injected", not blocked_injected,
str(blocked_injected))
for fab in ("cissp", "pmp", "cuda", "12+ years"):
blob = (report.get("tex", "") or "").lower()
check(f"no fabrication term in output: '{fab}'", fab not in blob)
# ββ Guaranteed PDF fallback + multi-engine resilience ββββββββββββββββββββββββ
print("[E] Guaranteed PDF fallback + multi-engine resilience")
import tempfile
import shutil as _sh
from src.latex_resume import render_text_to_pdf, latex_engines_available
_tmp = tempfile.mkdtemp()
_fb = os.path.join(_tmp, "fb.pdf")
_out = render_text_to_pdf(
"Jane Doe\nProduct Manager\n\nEXPERIENCE\nOwned the product roadmap.", _fb)
check("render_text_to_pdf() produces a non-empty PDF (no LaTeX engine needed)",
bool(_out) and os.path.exists(_fb) and os.path.getsize(_fb) > 0,
f"{os.path.getsize(_fb) if os.path.exists(_fb) else 0} bytes")
_sh.rmtree(_tmp, ignore_errors=True)
check("latex_engines_available() returns a list (multi-engine fallback)",
isinstance(latex_engines_available(), list))
api = read("api_server.py")
check("both LaTeX branches add a pdf_fallback flag", api.count("pdf_fallback") >= 4,
f"count={api.count('pdf_fallback')}")
check("API fallback uses render_text_to_pdf", "render_text_to_pdf" in api)
# ββ Panel <-> popup run sync βββββββββββββββββββββββββββββββββββββββββββββββββ
print("[F] Side-panel <-> popup run-state sync")
check("popup reflects a 'running' change from another surface",
"entry.status === 'running'" in popup)
check("popup surfaces the pdf_fallback note", "pdf_fallback" in popup)
print("-" * 70)
print("PASS - extraction junk-guard + tectonic fix + PDF fallback + sync verified"
if _ok else "FAIL - see above")
sys.exit(0 if _ok else 1)
|