From 10e0308332694d263466c3d0c8d4dfd42db8dad2 Mon Sep 17 00:00:00 2001 From: Owner Date: Mon, 12 Oct 2026 02:31:49 +0700 Subject: [PATCH] test: add Vitest unit tests for location-detector and country-flags --- src/lib/geo/tests/country-flags.test.ts | 17 +++++ src/lib/geo/tests/location-detector.test.ts | 76 +++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/lib/geo/tests/country-flags.test.ts create mode 100644 src/lib/geo/tests/location-detector.test.ts diff --git a/src/lib/geo/tests/country-flags.test.ts b/src/lib/geo/tests/country-flags.test.ts new file mode 100644 index 0000000..86ebf99 --- /dev/null +++ b/src/lib/geo/tests/country-flags.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, test } from "vitest"; +import { getCountryCode } from "@/lib/geo/country-flags"; + +describe("getCountryCode", () => { + test.each([ + ["egypt", "eg"], + ["germany", "de"], + ["united_states", "us"], + ["uk", "gb"], + ])("returns the ISO code for %s", (slug, expected) => { + expect(getCountryCode(slug)).toBe(expected); + }); + + test.each(["atlantis", "", "EGYPT", "worldwide"])("returns null for %j", (slug) => { + expect(getCountryCode(slug)).toBeNull(); + }); +}); diff --git a/src/lib/geo/tests/location-detector.test.ts b/src/lib/geo/tests/location-detector.test.ts new file mode 100644 index 0000000..7198a72 --- /dev/null +++ b/src/lib/geo/tests/location-detector.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, test } from "vitest"; +import { detectCountry } from "@/lib/geo/location-detector"; + +describe("detectCountry", () => { + describe("empty and invalid input", () => { + test("returns null for null", () => { + expect(detectCountry(null)).toBeNull(); + }); + + test.each(["", " ", " ", "\t\n"])("returns null for blank input %j", (input) => { + expect(detectCountry(input)).toBeNull(); + }); + + test.each(["!!!", "###", "@#$%^&*()", "🌍", "(.*)", "[", "\\"])( + "returns null for special characters only: %s", + (input) => { + expect(detectCountry(input)).toBeNull(); + }, + ); + + test.each(["Mars", "Earth", "Remote"])( + "returns null when no country is present: %s", + (input) => { + expect(detectCountry(input)).toBeNull(); + }, + ); + }); + + describe("exact match", () => { + test.each([ + ["Egypt", "egypt"], + ["Germany", "germany"], + ["Tokyo, Japan", "japan"], + ["Jakarta, Indonesia", "indonesia"], + ["Cairo", "egypt"], + ["New Zealand", "new_zealand"], + ["South Korea", "south_korea"], + ["Hong Kong", "hong_kong"], + ])("detects %s as %s", (input, expected) => { + expect(detectCountry(input)).toBe(expected); + }); + + test("is case-insensitive", () => { + expect(detectCountry("EGYPT")).toBe("egypt"); + }); + + test("ignores surrounding whitespace", () => { + expect(detectCountry(" Egypt ")).toBe("egypt"); + }); + + test("matches next to punctuation", () => { + expect(detectCountry("Cairo, Egypt!")).toBe("egypt"); + }); + }); + + describe("word boundaries", () => { + test.each([ + ["Romania", "romania"], + ["Somalia", "somalia"], + ["Nigeria", "nigeria"], + ["Tirana", "albania"], + ["Indiana", "united_states"], + ])("%s is not matched by the country hidden inside it", (input, expected) => { + expect(detectCountry(input)).toBe(expected); + }); + + test.each([ + ["Oman", "oman"], + ["Mali", "mali"], + ["Niger", "niger"], + ["Iran", "iran"], + ])("still matches the standalone word %s", (input, expected) => { + expect(detectCountry(input)).toBe(expected); + }); + }); +});