Spaces:
Sleeping
Sleeping
| #!/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) | |