From 017f35b0f49b44b93e2a511090b2c0c554f76259 Mon Sep 17 00:00:00 2001 From: Brian Schwartz Date: Thu, 16 Jul 2026 16:08:14 +0000 Subject: [PATCH] feat: show optional experience location on resume date lines Append role location after the date range in DOCX/PDF resumes, tighten template spacing, and render education as a single pipe-separated line. Co-authored-by: Cursor --- data/profile-dev.sample.json | 3 ++ data/profile.sample.json | 3 ++ lib/__tests__/resume-format.test.ts | 36 +++++++++++++++ lib/__tests__/resume-template.test.ts | 66 +++++++++++++++++++++++++++ lib/docx-resume.ts | 3 +- lib/profile.ts | 1 + lib/resume-format.ts | 5 +- lib/resume-template.ts | 31 ++++++------- 8 files changed, 128 insertions(+), 20 deletions(-) diff --git a/data/profile-dev.sample.json b/data/profile-dev.sample.json index 1a939e9..d513def 100644 --- a/data/profile-dev.sample.json +++ b/data/profile-dev.sample.json @@ -15,6 +15,7 @@ { "company": "Clarion Systems", "role": "Staff Software Engineer", + "location": "Remote", "start": "2022-07", "end": null, "bullets": [ @@ -28,6 +29,7 @@ { "company": "Beacon Labs", "role": "Senior Software Engineer", + "location": "Austin, TX", "start": "2019-04", "end": "2022-06", "bullets": [ @@ -40,6 +42,7 @@ { "company": "Trove Digital", "role": "Software Engineer", + "location": "Austin, TX", "start": "2016-08", "end": "2019-03", "bullets": [ diff --git a/data/profile.sample.json b/data/profile.sample.json index 150fbd1..6d89812 100644 --- a/data/profile.sample.json +++ b/data/profile.sample.json @@ -15,6 +15,7 @@ { "company": "Meridian Software", "role": "Director of Product Design", + "location": "Remote", "start": "2023-03", "end": null, "bullets": [ @@ -28,6 +29,7 @@ { "company": "Lumen Analytics", "role": "Senior Product Designer", + "location": "Chicago, IL", "start": "2020-06", "end": "2023-02", "bullets": [ @@ -41,6 +43,7 @@ { "company": "Clearpath Digital", "role": "UX Designer", + "location": "Chicago, IL", "start": "2017-08", "end": "2020-05", "bullets": [ diff --git a/lib/__tests__/resume-format.test.ts b/lib/__tests__/resume-format.test.ts index bbd37ac..439595a 100644 --- a/lib/__tests__/resume-format.test.ts +++ b/lib/__tests__/resume-format.test.ts @@ -96,6 +96,42 @@ describe("formatDateRange", () => { // Assert expect(range).toBe("December 2011 – January 2012"); }); + + it("omits the location segment entirely when location is undefined", () => { + // Arrange + const start = "2024-10"; + const end = null; + + // Act + const range = formatDateRange(start, end, undefined); + + // Assert + expect(range).toBe("October 2024 – Present"); + }); + + it("omits the location segment entirely when location is an empty string", () => { + // Arrange + const start = "2024-10"; + const end = null; + + // Act + const range = formatDateRange(start, end, ""); + + // Assert + expect(range).toBe("October 2024 – Present"); + }); + + it("appends a single location after the date range separated by ' | '", () => { + // Arrange + const start = "2023-01"; + const end = "2024-01"; + + // Act + const range = formatDateRange(start, end, "Chicago, IL"); + + // Assert + expect(range).toBe("January 2023 – January 2024 | Chicago, IL"); + }); }); describe("linesToBullets", () => { diff --git a/lib/__tests__/resume-template.test.ts b/lib/__tests__/resume-template.test.ts index 6d9b0c0..527dd39 100644 --- a/lib/__tests__/resume-template.test.ts +++ b/lib/__tests__/resume-template.test.ts @@ -50,6 +50,43 @@ describe("buildResumeHtml", () => { expect(html).toContain("
  • Shipped the thing.
  • "); }); + it("appends the role's location after the date range when location is present", () => { + // Arrange + const profile: ProfileData = { + experience: [ + { + company: "Anthropic", + role: "Staff Designer", + location: "Chicago, IL", + start: "2023-01", + end: null, + bullets: [], + }, + ], + }; + + // Act + const html = buildResumeHtml(profile, candidate); + + // Assert + expect(html).toContain("January 2023 – Present | Chicago, IL"); + }); + + it("omits the location segment when the role has no location", () => { + // Arrange + const profile: ProfileData = { + experience: [ + { company: "Anthropic", role: "Staff Designer", start: "2023-01", end: null, bullets: [] }, + ], + }; + + // Act + const html = buildResumeHtml(profile, candidate); + + // Assert + expect(html).toContain("January 2023 – Present"); + }); + it("renders multiple experience roles in the given order", () => { // Arrange const profile: ProfileData = { @@ -309,6 +346,35 @@ describe("buildResumeHtml", () => { expect(html).not.toContain("