From 539fb49c70ef057a68c34c6251be5c228cdeed90 Mon Sep 17 00:00:00 2001 From: JoshuaVSherman Date: Fri, 28 Aug 2026 16:32:53 -0400 Subject: [PATCH 1/2] feat(book-gig): add surrounding town mappings for Pembroke, Pulaski, Wirtz, and Huddleston --- deno.json | 2 +- src/book-gig/parser.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/deno.json b/deno.json index 09cb96a..733ad3c 100644 --- a/deno.json +++ b/deno.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/denoland/deno/main/cli/schemas/config-file.v1.json", "name": "@webjam/tools", - "version": "1.32.38", + "version": "1.32.39", "exports": "./src/uptime/cron.ts", "tasks": { "sheet-music:generate": "deno run --allow-read --allow-write src/sheet-music/generate_docx.ts", diff --git a/src/book-gig/parser.ts b/src/book-gig/parser.ts index 5c3ff6f..4180073 100644 --- a/src/book-gig/parser.ts +++ b/src/book-gig/parser.ts @@ -259,16 +259,25 @@ export const METRO_SURROUNDING: Record = { "Christiansburg", "Radford", "Floyd", + "Pembroke", + "Pulaski", + "Giles", ], "blacksburg": [ "Christiansburg", "Radford", "Floyd", + "Pembroke", + "Pulaski", + "Giles", ], "christiansburg": [ "Blacksburg", "Radford", "Floyd", + "Pembroke", + "Pulaski", + "Giles", ], "martinsville": [ "Bassett", @@ -277,6 +286,9 @@ export const METRO_SURROUNDING: Record = { "Stuart", "Stanleytown", "Rocky Mount", + "Axton", + "Ridgeway", + "Fieldale", ], "roanoke-salem": [ "Vinton", @@ -289,6 +301,8 @@ export const METRO_SURROUNDING: Record = { "Catawba", "Natural Bridge", "Moneta", + "Wirtz", + "Huddleston", ], "roanoke": [ "Vinton", @@ -301,6 +315,8 @@ export const METRO_SURROUNDING: Record = { "Catawba", "Natural Bridge", "Moneta", + "Wirtz", + "Huddleston", ], "salem": [ "Vinton", @@ -313,6 +329,8 @@ export const METRO_SURROUNDING: Record = { "Catawba", "Natural Bridge", "Moneta", + "Wirtz", + "Huddleston", ], "charlottesville": [ "Crozet", @@ -426,6 +444,8 @@ export const KNOWN_METROS: Record< "24153", ], }, + "wirtz": { slug: "roanoke-salem", city: "Wirtz", state: "VA", zips: ["24184"] }, + "huddleston": { slug: "roanoke-salem", city: "Huddleston", state: "VA", zips: ["24104"] }, "lynchburg": { slug: "lynchburg", city: "Lynchburg", @@ -457,6 +477,8 @@ export const KNOWN_METROS: Record< zips: ["24141", "24142", "24143"], }, "floyd": { slug: "blacksburg-christiansburg", city: "Floyd", state: "VA", zips: ["24091"] }, + "pembroke": { slug: "blacksburg-christiansburg", city: "Pembroke", state: "VA", zips: ["24136"] }, + "pulaski": { slug: "blacksburg-christiansburg", city: "Pulaski", state: "VA", zips: ["24301"] }, "blacksburg-christiansburg": { slug: "blacksburg-christiansburg", city: "Blacksburg", From 4f321306773ae8510df9375161fa5e3daeee3afb Mon Sep 17 00:00:00 2001 From: JoshuaVSherman Date: Wed, 2 Sep 2026 01:12:06 -0400 Subject: [PATCH 2/2] test(book-gig): add unit test coverage for new surrounding town and zip mappings --- test/book_gig.test.ts | 8 ++++++++ test/book_gig_parser.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/test/book_gig.test.ts b/test/book_gig.test.ts index a64cbb5..7aa8ea3 100644 --- a/test/book_gig.test.ts +++ b/test/book_gig.test.ts @@ -118,6 +118,14 @@ Deno.test("parseLocation: parses multi-city comma lists, and conjunctions, and s assert(loc3.surroundingCities.includes("Bedford")); assert(loc3.surroundingCities.includes("Vinton")); assert(loc3.surroundingCities.includes("Bassett")); + assert(loc3.surroundingCities.includes("Pembroke")); + assert(loc3.surroundingCities.includes("Pulaski")); + assert(loc3.surroundingCities.includes("Giles")); + assert(loc3.surroundingCities.includes("Wirtz")); + assert(loc3.surroundingCities.includes("Huddleston")); + assert(loc3.surroundingCities.includes("Axton")); + assert(loc3.surroundingCities.includes("Ridgeway")); + assert(loc3.surroundingCities.includes("Fieldale")); // Excluded towns beyond perimeter (Marion) and target cities assertEquals(loc3.surroundingCities.includes("Marion"), false); assertEquals(loc3.surroundingCities.includes("Salem"), false); diff --git a/test/book_gig_parser.test.ts b/test/book_gig_parser.test.ts index 7f599a5..45d1186 100644 --- a/test/book_gig_parser.test.ts +++ b/test/book_gig_parser.test.ts @@ -104,6 +104,23 @@ Deno.test("parseLocation: parses valid 5-digit zipcodes and known metros", () => assertEquals(loc2?.city, "Salem"); assertEquals(loc2?.state, "VA"); + // Newly mapped towns: Pembroke, Pulaski, Wirtz, Huddleston + const locPembroke = parseLocation("24136"); + assertEquals(locPembroke?.city, "Pembroke"); + assertEquals(locPembroke?.metroSlug, "blacksburg-christiansburg"); + + const locPulaski = parseLocation("24301"); + assertEquals(locPulaski?.city, "Pulaski"); + assertEquals(locPulaski?.metroSlug, "blacksburg-christiansburg"); + + const locWirtz = parseLocation("24184"); + assertEquals(locWirtz?.city, "Wirtz"); + assertEquals(locWirtz?.metroSlug, "roanoke-salem"); + + const locHuddleston = parseLocation("24104"); + assertEquals(locHuddleston?.city, "Huddleston"); + assertEquals(locHuddleston?.metroSlug, "roanoke-salem"); + // Unknown zip returns zip object without metro mapping const loc3 = parseLocation("90210"); assertEquals(loc3?.zip, "90210"); @@ -127,6 +144,14 @@ Deno.test("parseLocation: parses City, State and multi-city expressions", () => assert(loc2.surroundingCities.includes("Floyd")); assert(loc2.surroundingCities.includes("Radford")); assert(loc2.surroundingCities.includes("Christiansburg")); + assert(loc2.surroundingCities.includes("Pembroke")); + assert(loc2.surroundingCities.includes("Pulaski")); + assert(loc2.surroundingCities.includes("Giles")); + assert(loc2.surroundingCities.includes("Wirtz")); + assert(loc2.surroundingCities.includes("Huddleston")); + assert(loc2.surroundingCities.includes("Axton")); + assert(loc2.surroundingCities.includes("Ridgeway")); + assert(loc2.surroundingCities.includes("Fieldale")); assertEquals(loc2.surroundingCities.includes("Marion"), false); // Dynamic multi-city in NC