diff --git a/src/lib/edit/apply-overrides.test.ts b/src/lib/edit/apply-overrides.test.ts index 4af2e4bb..9da9756c 100644 --- a/src/lib/edit/apply-overrides.test.ts +++ b/src/lib/edit/apply-overrides.test.ts @@ -82,6 +82,48 @@ describe("applyOverrides", () => { expect(out.full_name).toBeUndefined(); }); + it("clears a stale phoneIsValid flag when the phone is overridden (#70 review)", () => { + const parsed: HeuristicParsedResume = { + ...baseParsed(), + phone: "555-invalid", + phoneIsValid: false, + }; + // User fixes the number → the old `false` must not survive, else the + // scorer keeps awarding half credit on the corrected phone. + const { parsed: out } = applyOverrides( + parsed, + "raw", + makeSections(), + { phone: "(312) 555-0123" }, + {}, + {}, + [], + ); + expect(out.phone).toBe("(312) 555-0123"); + expect(out.phoneIsValid).toBeUndefined(); + // Original untouched. + expect(parsed.phoneIsValid).toBe(false); + }); + + it("clears a stale phoneIsValid flag when the phone is cleared (#70 review)", () => { + const parsed: HeuristicParsedResume = { + ...baseParsed(), + phone: "555-invalid", + phoneIsValid: false, + }; + const { parsed: out } = applyOverrides( + parsed, + "raw", + makeSections(), + { phone: "" }, + {}, + {}, + [], + ); + expect(out.phone).toBeUndefined(); + expect(out.phoneIsValid).toBeUndefined(); + }); + it("replaces experience header fields by index", () => { const parsed = baseParsed(); const { parsed: out } = applyOverrides( diff --git a/src/lib/edit/apply-overrides.ts b/src/lib/edit/apply-overrides.ts index f91fc2d1..615b81e7 100644 --- a/src/lib/edit/apply-overrides.ts +++ b/src/lib/edit/apply-overrides.ts @@ -211,6 +211,11 @@ export function applyOverrides( } else { nextParsed[key] = ov; } + // The original `phoneIsValid` flag is now stale — it described the parsed + // phone, not the user-supplied one. Drop it so the scorer re-grades the + // edited number as validity-unknown (backward-compatible full credit) + // instead of carrying the old false → permanent half credit. (#70 review) + if (key === "phone") delete nextParsed.phoneIsValid; } // ── Experience headers ────────────────────────────────────────────────── diff --git a/src/lib/heuristics/extract/contact.ts b/src/lib/heuristics/extract/contact.ts index 0aa0e391..53410256 100644 --- a/src/lib/heuristics/extract/contact.ts +++ b/src/lib/heuristics/extract/contact.ts @@ -20,6 +20,9 @@ import { firstMatch, allMatches } from "./shared.ts"; export interface ContactExtractionResult { email?: string; phone?: string; + /** libphonenumber isValid() result for the extracted phone. Undefined when + * no phone was found or the caller did not supply validity signal. */ + phoneIsValid?: boolean; linkedin_url?: string; github_url?: string; portfolio_url?: string; @@ -233,6 +236,7 @@ function scan(lines: PdfLine[], joined: string): ContactScanResult { return { email, phone, + ...(phone !== undefined ? { phoneIsValid: phoneResult?.isValid } : {}), linkedin_url: normalizeUrl(linkedin), github_url: normalizeUrl(github), portfolio_url: normalizeUrl(portfolio), @@ -387,6 +391,7 @@ export function extractContact( return { email: primary.email ?? fallback.email, phone: primary.phone ?? fallback.phone, + phoneIsValid: primary.phone ? primary.phoneIsValid : fallback.phoneIsValid, linkedin_url: normalizeUrl(linkedin.value), github_url: normalizeUrl(github.value), portfolio_url: normalizeUrl(portfolio.value), diff --git a/src/lib/heuristics/openresume.ts b/src/lib/heuristics/openresume.ts index 276f08c4..219a434e 100644 --- a/src/lib/heuristics/openresume.ts +++ b/src/lib/heuristics/openresume.ts @@ -198,6 +198,9 @@ function buildHeuristicResult( ...splitGivenFamilyName(name.value), ...(contact.email ? { email: contact.email } : {}), ...(contact.phone ? { phone: contact.phone } : {}), + ...(contact.phone && contact.phoneIsValid !== undefined + ? { phoneIsValid: contact.phoneIsValid } + : {}), ...(contact.location ? { location: contact.location } : {}), ...(contact.linkedin_url ? { linkedin_url: contact.linkedin_url } : {}), ...(contact.github_url ? { github_url: contact.github_url } : {}), diff --git a/src/lib/heuristics/regex-fallback.ts b/src/lib/heuristics/regex-fallback.ts index 0c9ee216..babbfd93 100644 --- a/src/lib/heuristics/regex-fallback.ts +++ b/src/lib/heuristics/regex-fallback.ts @@ -80,6 +80,7 @@ export function runRegexFallback( const phoneResult = findFirstPhone(rawText, region); if (phoneResult) { parsed.phone = phoneResult.formatted; + parsed.phoneIsValid = phoneResult.isValid; fieldConfidence.phone = 0.6; fieldsFilled.push("phone"); } diff --git a/src/lib/heuristics/types.ts b/src/lib/heuristics/types.ts index f9d317f3..d4683a77 100644 --- a/src/lib/heuristics/types.ts +++ b/src/lib/heuristics/types.ts @@ -123,6 +123,10 @@ export type HeuristicParsedResume = Partial & { skills: string[]; experience: ResumeExperience[]; education: ResumeEducation[]; + /** libphonenumber isValid() result for the extracted phone — plumbed from + * the extraction layer so the scorer can apply validity-aware credit without + * importing libphonenumber-js (which would break the entry-chunk budget). */ + phoneIsValid?: boolean; }; /** Confidence per extracted field (0..1). Fields not in the map default to 0. */ diff --git a/src/lib/score/score.test.ts b/src/lib/score/score.test.ts index 835d3d10..d07c74e4 100644 --- a/src/lib/score/score.test.ts +++ b/src/lib/score/score.test.ts @@ -666,4 +666,61 @@ describe("computeAnonymousAtsScore", () => { expect(result.completeness.redactedDates).toBeFalsy(); }); }); + + describe("validity-aware phone completeness (#70)", () => { + it("awards full credit for a phone that is present, confident, and valid", () => { + const result = computeAnonymousAtsScore( + makeAnonInput({ + parsed: { ...makeAnonInput().parsed, phone: "(312) 555-0123", phoneIsValid: true }, + fieldConfidence: { ...makeAnonInput().fieldConfidence, phone: 0.9 }, + }), + ); + expect(result.completeness.missing).not.toContain("phone"); + }); + + it("awards full credit when phoneIsValid is absent (backward-compatible)", () => { + const result = computeAnonymousAtsScore( + makeAnonInput({ + parsed: { ...makeAnonInput().parsed, phone: "(312) 555-0123", phoneIsValid: undefined }, + fieldConfidence: { ...makeAnonInput().fieldConfidence, phone: 0.9 }, + }), + ); + expect(result.completeness.missing).not.toContain("phone"); + }); + + it("awards half credit for a phone that is present but invalid (phoneIsValid===false)", () => { + const withPhone = makeAnonInput(); + const withoutPhone = makeAnonInput({ + parsed: { ...makeAnonInput().parsed, phone: undefined }, + fieldConfidence: { ...makeAnonInput().fieldConfidence, phone: 0 }, + }); + const invalidPhone = makeAnonInput({ + parsed: { ...makeAnonInput().parsed, phone: "555-invalid", phoneIsValid: false }, + fieldConfidence: { ...makeAnonInput().fieldConfidence, phone: 0.85 }, + }); + // Half credit: invalid phone scores above absent (0) but below valid (1) + expect(invalidPhone.parsed.phoneIsValid).toBe(false); + const invalidResult = computeAnonymousAtsScore(invalidPhone); + const absentResult = computeAnonymousAtsScore(withoutPhone); + const validResult = computeAnonymousAtsScore(withPhone); + // Invalid phone is still in missing (passed: false) + expect(invalidResult.completeness.missing).toContain("phone"); + // But it earns more completeness score than absent phone + expect(invalidResult.completeness.score).toBeGreaterThan(absentResult.completeness.score); + // And strictly less than a fully valid phone — a <= bound would stay + // green even if invalid phones were granted full credit (the exact way + // the feature would break). (#70 review) + expect(invalidResult.completeness.score).toBeLessThan(validResult.completeness.score); + }); + + it("does not credit phone when confidence is below the floor", () => { + const result = computeAnonymousAtsScore( + makeAnonInput({ + parsed: { ...makeAnonInput().parsed, phone: "(312) 555-0123", phoneIsValid: true }, + fieldConfidence: { ...makeAnonInput().fieldConfidence, phone: 0.3 }, + }), + ); + expect(result.completeness.missing).toContain("phone"); + }); + }); }); diff --git a/src/lib/score/score.ts b/src/lib/score/score.ts index 066bab5e..9c973847 100644 --- a/src/lib/score/score.ts +++ b/src/lib/score/score.ts @@ -57,11 +57,15 @@ export const WEIGHTS = { * section), so the retired "pool everything, subtract skills" side-channel is * gone. The experience-completeness check now asks "is there a non-empty * experience section?" rather than "did we see any bullet anywhere?". + * - 1.4 (2026-06-23): validity-aware phone completeness credit (#70) — a + * parsed-but-invalid phone (libphonenumber isValid===false) earns half + * completeness credit instead of full; valid phones unchanged, absent + * unchanged. */ // Internal-only: surfaced to the UI via the `algoVersion` score field, not // imported by name anywhere — so it stays unexported to satisfy the dead-code // gate (fallow flags exported symbols with no external consumer). -const ATS_SCORE_ALGO_VERSION = "1.3"; +const ATS_SCORE_ALGO_VERSION = "1.4"; // ── Shared scoring rules ──────────────────────────────────────────────────── // @@ -523,6 +527,10 @@ export interface AnonymousAtsScoreInput { full_name?: string; email?: string; phone?: string; + /** libphonenumber isValid() result plumbed from extraction (#70). When + * present and false, the phone earns half completeness credit. When absent + * or undefined with a present phone, backward-compatible full credit. */ + phoneIsValid?: boolean; location?: string; linkedin_url?: string; summary?: string; @@ -568,6 +576,8 @@ export interface AnonymousAtsScoreInput { } const ANON_CONTACT_CONFIDENCE_FLOOR = 0.5; +/** Completeness credit for a phone that parsed but failed libphonenumber isValid(). */ +const PHONE_INVALID_CREDIT = 0.5; const ANON_MIN_BULLETS_TO_GRADE = 3; /** Word-count floor for section bullet extraction. Set to 1 so the displayed * bullet count matches what the user can see in the PDF — every line that @@ -726,11 +736,26 @@ export function computeAnonymousAtsScore( for (const f of ANON_CONTACT_FIELDS) { const value = input.parsed[f.key]; const conf = input.fieldConfidence[f.key] ?? 0; - completenessChecks.push({ - key: `contact.${f.key}`, - passed: Boolean(value) && conf >= ANON_CONTACT_CONFIDENCE_FLOOR, - label: f.label, - }); + const present = Boolean(value) && conf >= ANON_CONTACT_CONFIDENCE_FLOOR; + if (f.key === "phone") { + // Validity-aware phone credit (#70): + // present + valid (or validity unknown) → full credit (passed: true) + // present + explicitly invalid → half credit (passed: false, credit: 0.5) + // absent or below conf floor → zero credit (passed: false) + const phoneInvalid = present && input.parsed.phoneIsValid === false; + completenessChecks.push({ + key: `contact.${f.key}`, + passed: present && !phoneInvalid, + label: f.label, + ...(phoneInvalid ? { credit: PHONE_INVALID_CREDIT } : {}), + }); + } else { + completenessChecks.push({ + key: `contact.${f.key}`, + passed: present, + label: f.label, + }); + } } const expEntries = input.parsed.experience ?? []; const eduEntries = input.parsed.education ?? []; diff --git a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-additional-skills.expected.json b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-additional-skills.expected.json index aeb90fcc..1310e809 100644 --- a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-additional-skills.expected.json +++ b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-additional-skills.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "projects", "skills", "website_url" @@ -66,6 +67,6 @@ "scanned": false }, "bulletCount": 0, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-classic.expected.json b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-classic.expected.json index e7fa5d84..9d2dbb84 100644 --- a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-classic.expected.json +++ b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-classic.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -64,6 +65,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-minimal.expected.json b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-minimal.expected.json index 851150a1..98c2b296 100644 --- a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-minimal.expected.json +++ b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-minimal.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 7, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-nonstandard-headers.expected.json b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-nonstandard-headers.expected.json index 02058156..87be364c 100644 --- a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-nonstandard-headers.expected.json +++ b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-nonstandard-headers.expected.json @@ -18,6 +18,7 @@ "full_name", "given_name", "phone", + "phoneIsValid", "projects", "skills", "summary", @@ -66,6 +67,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-two-column.expected.json b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-two-column.expected.json index 46e19ba6..d67e0636 100644 --- a/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-two-column.expected.json +++ b/tests/fixtures/pdfs/google-docs/google-docs-skia-proxy-two-column.expected.json @@ -24,6 +24,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "projects", "skills", "website_url" @@ -72,6 +73,6 @@ "scanned": false }, "bulletCount": 13, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/latex/awesome-cv-cv.expected.json b/tests/fixtures/pdfs/latex/awesome-cv-cv.expected.json index 543dd0a6..ef8725bc 100644 --- a/tests/fixtures/pdfs/latex/awesome-cv-cv.expected.json +++ b/tests/fixtures/pdfs/latex/awesome-cv-cv.expected.json @@ -22,6 +22,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -67,6 +68,6 @@ "scanned": false }, "bulletCount": 52, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/latex/awesome-cv-resume.expected.json b/tests/fixtures/pdfs/latex/awesome-cv-resume.expected.json index 91a34188..b5bfa520 100644 --- a/tests/fixtures/pdfs/latex/awesome-cv-resume.expected.json +++ b/tests/fixtures/pdfs/latex/awesome-cv-resume.expected.json @@ -22,6 +22,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "summary", "website_url" ], @@ -67,6 +68,6 @@ "scanned": false }, "bulletCount": 30, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/latex/deedy-resume-macfonts.expected.json b/tests/fixtures/pdfs/latex/deedy-resume-macfonts.expected.json index 56e23e50..13d31b6a 100644 --- a/tests/fixtures/pdfs/latex/deedy-resume-macfonts.expected.json +++ b/tests/fixtures/pdfs/latex/deedy-resume-macfonts.expected.json @@ -24,6 +24,7 @@ "heuristic_achievements", "linkedin_url", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -72,6 +73,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/latex/deedy-resume-openfonts.expected.json b/tests/fixtures/pdfs/latex/deedy-resume-openfonts.expected.json index 56e23e50..13d31b6a 100644 --- a/tests/fixtures/pdfs/latex/deedy-resume-openfonts.expected.json +++ b/tests/fixtures/pdfs/latex/deedy-resume-openfonts.expected.json @@ -24,6 +24,7 @@ "heuristic_achievements", "linkedin_url", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -72,6 +73,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/latex/header-as-name-functional-resume.expected.json b/tests/fixtures/pdfs/latex/header-as-name-functional-resume.expected.json index 34d8a7be..ae48dbc3 100644 --- a/tests/fixtures/pdfs/latex/header-as-name-functional-resume.expected.json +++ b/tests/fixtures/pdfs/latex/header-as-name-functional-resume.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "summary", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 5, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/chromium-asymmetric-sidebar.expected.json b/tests/fixtures/pdfs/unknown/chromium-asymmetric-sidebar.expected.json index 96245c45..9fb73f88 100644 --- a/tests/fixtures/pdfs/unknown/chromium-asymmetric-sidebar.expected.json +++ b/tests/fixtures/pdfs/unknown/chromium-asymmetric-sidebar.expected.json @@ -21,6 +21,7 @@ "given_name", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -69,6 +70,6 @@ "scanned": false }, "bulletCount": 11, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/chromium-qualified-experience-headers.expected.json b/tests/fixtures/pdfs/unknown/chromium-qualified-experience-headers.expected.json index 217bb47d..e4c7692a 100644 --- a/tests/fixtures/pdfs/unknown/chromium-qualified-experience-headers.expected.json +++ b/tests/fixtures/pdfs/unknown/chromium-qualified-experience-headers.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -64,6 +65,6 @@ "scanned": false }, "bulletCount": 0, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/chromium-two-column-sidebar.expected.json b/tests/fixtures/pdfs/unknown/chromium-two-column-sidebar.expected.json index 41025e3d..6dbc3af2 100644 --- a/tests/fixtures/pdfs/unknown/chromium-two-column-sidebar.expected.json +++ b/tests/fixtures/pdfs/unknown/chromium-two-column-sidebar.expected.json @@ -22,6 +22,7 @@ "heuristic_achievements", "location", "phone", + "phoneIsValid", "projects", "skills", "summary", @@ -71,6 +72,6 @@ "scanned": false }, "bulletCount": 27, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/name-set-apart-tagline.expected.json b/tests/fixtures/pdfs/unknown/name-set-apart-tagline.expected.json index 6c1b92ad..ea7b1b10 100644 --- a/tests/fixtures/pdfs/unknown/name-set-apart-tagline.expected.json +++ b/tests/fixtures/pdfs/unknown/name-set-apart-tagline.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "summary", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 4, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/openresume-react-pdf.expected.json b/tests/fixtures/pdfs/unknown/openresume-react-pdf.expected.json index 60a74cb2..d21aede3 100644 --- a/tests/fixtures/pdfs/unknown/openresume-react-pdf.expected.json +++ b/tests/fixtures/pdfs/unknown/openresume-react-pdf.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/single-word-name-mononym.expected.json b/tests/fixtures/pdfs/unknown/single-word-name-mononym.expected.json index a05c61dd..7208bc9f 100644 --- a/tests/fixtures/pdfs/unknown/single-word-name-mononym.expected.json +++ b/tests/fixtures/pdfs/unknown/single-word-name-mononym.expected.json @@ -19,6 +19,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -63,6 +64,6 @@ "scanned": false }, "bulletCount": 0, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/student-projects-activities-singlecol.expected.json b/tests/fixtures/pdfs/unknown/student-projects-activities-singlecol.expected.json index 6b1b46df..9779ca8e 100644 --- a/tests/fixtures/pdfs/unknown/student-projects-activities-singlecol.expected.json +++ b/tests/fixtures/pdfs/unknown/student-projects-activities-singlecol.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "projects", "skills", "website_url" @@ -66,6 +67,6 @@ "scanned": false }, "bulletCount": 19, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/two-column-achievements-sidebar.expected.json b/tests/fixtures/pdfs/unknown/two-column-achievements-sidebar.expected.json index 60995068..845b7552 100644 --- a/tests/fixtures/pdfs/unknown/two-column-achievements-sidebar.expected.json +++ b/tests/fixtures/pdfs/unknown/two-column-achievements-sidebar.expected.json @@ -21,6 +21,7 @@ "heuristic_achievements", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -70,6 +71,6 @@ "scanned": false }, "bulletCount": 16, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/weasyprint-cairo-classic.expected.json b/tests/fixtures/pdfs/unknown/weasyprint-cairo-classic.expected.json index 2965b9bf..f9f917ee 100644 --- a/tests/fixtures/pdfs/unknown/weasyprint-cairo-classic.expected.json +++ b/tests/fixtures/pdfs/unknown/weasyprint-cairo-classic.expected.json @@ -20,6 +20,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "skills", "summary", "website_url" @@ -64,6 +65,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/weasyprint-cairo-minimal.expected.json b/tests/fixtures/pdfs/unknown/weasyprint-cairo-minimal.expected.json index 851150a1..98c2b296 100644 --- a/tests/fixtures/pdfs/unknown/weasyprint-cairo-minimal.expected.json +++ b/tests/fixtures/pdfs/unknown/weasyprint-cairo-minimal.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 7, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/weasyprint-cairo-nonstandard-headers.expected.json b/tests/fixtures/pdfs/unknown/weasyprint-cairo-nonstandard-headers.expected.json index 02058156..87be364c 100644 --- a/tests/fixtures/pdfs/unknown/weasyprint-cairo-nonstandard-headers.expected.json +++ b/tests/fixtures/pdfs/unknown/weasyprint-cairo-nonstandard-headers.expected.json @@ -18,6 +18,7 @@ "full_name", "given_name", "phone", + "phoneIsValid", "projects", "skills", "summary", @@ -66,6 +67,6 @@ "scanned": false }, "bulletCount": 8, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.expected.json b/tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.expected.json index 9fbd9fb7..4cef7605 100644 --- a/tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.expected.json +++ b/tests/fixtures/pdfs/unknown/weasyprint-cairo-two-column.expected.json @@ -24,6 +24,7 @@ "linkedin_url", "location", "phone", + "phoneIsValid", "projects", "skills", "website_url" @@ -72,6 +73,6 @@ "scanned": false }, "bulletCount": 13, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/word/chanchal-sharma-bulleted-skills.expected.json b/tests/fixtures/pdfs/word/chanchal-sharma-bulleted-skills.expected.json index 089caa04..330c75a4 100644 --- a/tests/fixtures/pdfs/word/chanchal-sharma-bulleted-skills.expected.json +++ b/tests/fixtures/pdfs/word/chanchal-sharma-bulleted-skills.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 3, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/word/chanchal-sharma-sample.expected.json b/tests/fixtures/pdfs/word/chanchal-sharma-sample.expected.json index 0411e61e..e9278a2f 100644 --- a/tests/fixtures/pdfs/word/chanchal-sharma-sample.expected.json +++ b/tests/fixtures/pdfs/word/chanchal-sharma-sample.expected.json @@ -19,6 +19,7 @@ "given_name", "location", "phone", + "phoneIsValid", "skills", "website_url" ], @@ -65,6 +66,6 @@ "scanned": false }, "bulletCount": 3, - "algoVersion": "1.3" + "algoVersion": "1.4" } } diff --git a/tests/fixtures/pdfs/word/openresume-laverne-word-quartz.expected.json b/tests/fixtures/pdfs/word/openresume-laverne-word-quartz.expected.json index 98a98375..a9861e40 100644 --- a/tests/fixtures/pdfs/word/openresume-laverne-word-quartz.expected.json +++ b/tests/fixtures/pdfs/word/openresume-laverne-word-quartz.expected.json @@ -66,6 +66,6 @@ "scanned": false }, "bulletCount": 6, - "algoVersion": "1.3" + "algoVersion": "1.4" } }