src/lib/locations.test.ts
Rama main · réplica de lectura del repositorio original.
import { describe, expect, it } from "vitest";
import {
formatPlaceContext,
geocodeResultLabel,
geocodeResultToLocation,
unrepeated,
} from "./locations";
import type { GeocodeResult } from "@/lib/api/geocoding";
describe("formatPlaceContext", () => {
it("puts the region before the country", () => {
expect(formatPlaceContext("Cebu", "Philippines")).toBe("Cebu, Philippines");
});
it("says whichever one it has where it has only one", () => {
expect(formatPlaceContext(null, "Philippines")).toBe("Philippines");
expect(formatPlaceContext("Cebu", undefined)).toBe("Cebu");
});
it("answers null for neither, blanks included", () => {
// Null rather than "" so a caller can tell "nowhere was named" from a name.
expect(formatPlaceContext(null, null)).toBeNull();
expect(formatPlaceContext(" ", "")).toBeNull();
});
});
describe("unrepeated", () => {
it("keeps a part the labels do not hold", () => {
expect(unrepeated("Surat Thani Province", "Ko Tao")).toBe(
"Surat Thani Province",
);
});
it("drops a part equal to a part of a label, whatever its case", () => {
expect(unrepeated("Philippines", "Philippines")).toBeNull();
expect(unrepeated("thailand", "Ko Tao, Thailand")).toBeNull();
expect(unrepeated("Cebu", "Moalboal", " cebu ")).toBeNull();
});
it("compares whole parts, never substrings", () => {
// "Cebu" is context for a place called Cebu City, not a repeat of it.
expect(unrepeated("Cebu", "Cebu City, Philippines")).toBe("Cebu");
});
it("has nothing to say for a blank or missing part", () => {
expect(unrepeated(null, "Ko Tao")).toBeNull();
expect(unrepeated(undefined, "Ko Tao")).toBeNull();
expect(unrepeated(" ", "Ko Tao")).toBeNull();
});
it("ignores a missing label", () => {
expect(unrepeated("Cebu", null, undefined)).toBe("Cebu");
});
});
describe("geocodeResultToLocation", () => {
const DAHAB: GeocodeResult = {
latitude: 28.4949,
longitude: 34.5136,
location: "Dahab, South Sinai Governorate, Egypt",
name: "Dahab",
region: "South Sinai Governorate",
country: "Egypt",
attribution: "Data © OpenStreetMap contributors, ODbL 1.0.",
bbox_south: 28.45,
bbox_north: 28.54,
bbox_west: 34.47,
bbox_east: 34.55,
};
it("saves the API's composed name unchanged", () => {
// The place, its region and its country, composed once by the API for a
// search and a pin alike - so nothing here joins it from the parts.
expect(geocodeResultToLocation(DAHAB).name).toBe(
"Dahab, South Sinai Governorate, Egypt",
);
expect(
geocodeResultToLocation({
...DAHAB,
region: "Somewhere Else",
country: "Nowhere",
}).name,
).toBe("Dahab, South Sinai Governorate, Egypt");
});
it("ignores the result's own bare name, which is not what a log records", () => {
// "Dahab" alone says nothing about which Dahab. It still has a job in the
// site search, where it is the row's title - but not in the field.
expect(geocodeResultToLocation({ ...DAHAB, name: "Dahab" }).name).toBe(
"Dahab, South Sinai Governorate, Egypt",
);
expect(geocodeResultToLocation({ ...DAHAB, name: null }).name).toBe(
"Dahab, South Sinai Governorate, Egypt",
);
});
it("takes the centre and the extent a forward search answered with", () => {
// These are the *place's*, which is what a search by name returns. A
// reverse geocode does not come through here, because its coordinates are
// the host's own pin.
expect(geocodeResultToLocation(DAHAB)).toEqual({
name: "Dahab, South Sinai Governorate, Egypt",
latitude: 28.4949,
longitude: 34.5136,
bbox_south: 28.45,
bbox_north: 28.54,
bbox_west: 34.47,
bbox_east: 34.55,
});
});
it("leaves the box out whole when the provider gave none", () => {
// The API sends all four or nothing, and a half box is refused on the way
// back in - so an absent one must stay absent rather than become a corner.
expect(
geocodeResultToLocation({
...DAHAB,
bbox_south: null,
bbox_north: null,
bbox_west: null,
bbox_east: null,
}),
).toMatchObject({
bbox_south: null,
bbox_north: null,
bbox_west: null,
bbox_east: null,
});
});
});
describe("geocodeResultLabel", () => {
const MOALBOAL: GeocodeResult = {
latitude: 9.94,
longitude: 123.39,
location: "Moalboal, Cebu, Philippines",
name: "Moalboal",
region: "Cebu",
country: "Philippines",
attribution: "Data © OpenStreetMap contributors, ODbL 1.0.",
};
it("reads, as one line, what picking the row saves", () => {
const { name, context } = geocodeResultLabel(MOALBOAL);
expect({ name, context }).toEqual({
name: "Moalboal",
context: "Cebu, Philippines",
});
expect([name, context].join(", ")).toBe(
geocodeResultToLocation(MOALBOAL).name,
);
});
it("drops a hint part the name already says", () => {
expect(
geocodeResultLabel({
...MOALBOAL,
location: "Philippines",
name: "Philippines",
region: null,
}),
).toEqual({ name: "Philippines", context: null });
});
it("reads a result with no name of its own as its location alone", () => {
// An address-only row: the API put its finest address part in the name's
// place, so every part a hint could add is already in `location`.
expect(
geocodeResultLabel({
...MOALBOAL,
location: "Panagsama Road, Cebu, Philippines",
name: null,
}),
).toEqual({ name: "Panagsama Road, Cebu, Philippines", context: null });
});
});