Skip to content

Commit

Permalink
User numberParser from core packages
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniave committed Dec 5, 2024
1 parent d14bd72 commit 5efd5b3
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 110 deletions.
84 changes: 41 additions & 43 deletions src/packages/coordinate-search/CoordinateInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import {
getCurrentOptionValues,
showDropdown
} from "./test-utils";
import { NumberParserService } from "@open-pioneer/runtime";
import { NumberParser } from "@open-pioneer/core";

beforeEach(() => {
disableReactActWarnings();
});

it("should successfully create a coordinate input component", async () => {
const { mapId, registry } = await setupMap();

const injectedServices = createServiceOptions({ registry });
const { mapId, injectedServices } = await setUp();
render(
<PackageContextProvider services={injectedServices}>
<CoordinateInput mapId={mapId} data-testid="coordinate-input" />
Expand All @@ -42,9 +42,8 @@ it("should successfully create a coordinate input component", async () => {
});

it("should successfully create a coordinate input component with additional css classes", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<CoordinateInput mapId={mapId} className="test" data-testid="coordinate-input" />
Expand All @@ -58,9 +57,8 @@ it("should successfully create a coordinate input component with additional css

it("should successfully create a coordinate input component with external input", async () => {
const input = [761166, 6692084];
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -74,9 +72,8 @@ it("should successfully create a coordinate input component with external input"
});

it("should successfully create a coordinate input component with string placeholder", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -94,9 +91,8 @@ it("should successfully create a coordinate input component with string placehol
});

it("should successfully create a coordinate input component without a string placeholder", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -110,10 +106,9 @@ it("should successfully create a coordinate input component without a string pla
});

it("should successfully create a coordinate input component with coordinate placeholder", async () => {
const { mapId, registry } = await setupMap();
const coord: Coordinate = [408000, 5600000];

const injectedServices = createServiceOptions({ registry });
const { mapId, injectedServices } = await setUp();
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -127,7 +122,7 @@ it("should successfully create a coordinate input component with coordinate plac
});

it("should successfully create a coordinate input component with known projections", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();
const projections = [
{
label: "EPSG:25832",
Expand All @@ -147,7 +142,6 @@ it("should successfully create a coordinate input component with known projectio
}
];

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -169,9 +163,8 @@ it("should successfully create a coordinate input component with known projectio
});

it("should successfully create a coordinate input component with default projections", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -189,8 +182,7 @@ it("should successfully create a coordinate input component with default project
});

it("should update coordinates in selected option", async () => {
const { mapId, registry } = await setupMap();
const injectedServices = createServiceOptions({ registry });
const { mapId, injectedServices } = await setUp();
const initialInput = [851594.11, 6789283.95];
const updatedInput = [860000, 6900000.95];

Expand All @@ -216,10 +208,9 @@ it("should update coordinates in selected option", async () => {

it("should display transformed coordinates in selected option", async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const input = [851594.11, 6789283.95];
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand Down Expand Up @@ -257,9 +248,8 @@ it(
},
async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
let searchedCoords: Coordinate = [];
let callbackProj: Projection | undefined = undefined;
render(
Expand Down Expand Up @@ -293,9 +283,8 @@ it(
},
async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
let callbackProj: Projection | undefined = undefined;
let searchedCoords: Coordinate = [];
let called = false;
Expand Down Expand Up @@ -331,9 +320,8 @@ it(
},
async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
let cleared: boolean = false;
render(
<PackageContextProvider services={injectedServices}>
Expand Down Expand Up @@ -365,10 +353,9 @@ it(

it("should successfully copy to clipboard if copy button is clicked", async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();
let copiedText = "";

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand Down Expand Up @@ -410,10 +397,9 @@ it("should successfully copy to clipboard if copy button is clicked", async () =

it("should validate the input and show the correct tooltip message", async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const tooltipHelper = createTooltipHelper();
const { mapId, injectedServices } = await setUp("de");

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand Down Expand Up @@ -451,7 +437,7 @@ it("should validate the input and show the correct tooltip message", async () =>
await user.click(coordInput);
await user.paste("a,b c,d");
const tooltip4 = await tooltipHelper.waitForChange();
expect(tooltip4).toBe("tooltip.dividerDe");
expect(tooltip4).toBe("tooltip.invalidNumbers");

await user.clear(coordInput);
await user.click(coordInput);
Expand All @@ -463,15 +449,14 @@ it("should validate the input and show the correct tooltip message", async () =>
await user.click(coordInput);
await user.paste("a b");
const tooltip6 = await tooltipHelper.waitForChange();
expect(tooltip6).toBe("tooltip.dividerDe"); // TODO wrong error
expect(tooltip6).toBe("tooltip.invalidNumbers");
});

it("should validate if the user input is within the extent of the selected projection", async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const tooltipHelper = createTooltipHelper();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -496,9 +481,8 @@ it("should validate if the user input is within the extent of the selected proje

it("should validate input property is within the extent of the selected projection", async () => {
const user = userEvent.setup();
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices} locale="de">
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -520,9 +504,8 @@ it("should validate input property is within the extent of the selected projecti
});

it("should not show copy button on string placeholder", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -537,9 +520,8 @@ it("should not show copy button on string placeholder", async () => {
});

it("should show copy button on coordinate placeholder", async () => {
const { mapId, registry } = await setupMap();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand All @@ -559,10 +541,9 @@ it("should show copy button on coordinate placeholder", async () => {
});

it("should show clear button on coordinate placeholder", async () => {
const { mapId, registry } = await setupMap();
const user = userEvent.setup();
const { mapId, injectedServices } = await setUp();

const injectedServices = createServiceOptions({ registry });
render(
<PackageContextProvider services={injectedServices}>
<MapContainer mapId={mapId} data-testid="map" />
Expand Down Expand Up @@ -650,3 +631,20 @@ function createTooltipHelper() {
}
};
}

async function setUp(locale: string = "en") {
const { mapId, registry } = await setupMap();
const numberParser = new NumberParser(locale);
const numberParserService = {
parseNumber: (number) => {
return numberParser.parse(number);
}
} satisfies Partial<NumberParserService>;

const injectedServices = {
...createServiceOptions({ registry }),
"runtime.NumberParserService": numberParserService
};

return { mapId, injectedServices };
}
26 changes: 17 additions & 9 deletions src/packages/coordinate-search/CoordinateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import {
import { MapModelProps, useMapModel } from "@open-pioneer/map";
import { CommonComponentProps, useCommonComponentProps, useEvent } from "@open-pioneer/react-utils";
import { useReactiveSnapshot } from "@open-pioneer/reactivity";
import { PackageIntl } from "@open-pioneer/runtime";
import { NumberParserService, PackageIntl } from "@open-pioneer/runtime";
import { Coordinate } from "ol/coordinate";
import { get as getProjection, Projection, ProjectionLike, transform } from "ol/proj";
import { useIntl } from "open-pioneer:react-hooks";
import { useIntl, useService } from "open-pioneer:react-hooks";
import { FC, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { CoordinateInputField } from "./CoordinateInputField";
import { formatCoordinates, parseCoordinates, ParseResult } from "./coordinates";
Expand Down Expand Up @@ -228,13 +228,14 @@ function useCoordinateState(
onSelect: (validationResult: ParseResult) => void
): [string, (value: string) => void, ParseResult] {
const intl = useIntl();
const numberParser = useService<NumberParserService>("runtime.NumberParserService");

const [model] = useState(() => new StateModel(intl, selectedProjection));
const [model] = useState(() => new StateModel(intl, selectedProjection, numberParser));
useEffect(() => {
const triggerSelect =
inputProp !== model.inputProp || selectedProjection !== model.selectedProjection;

model.setIntl(intl);
model.setI18n(intl, numberParser);
model.setInputProp(inputProp);
model.setSelectedProjection(selectedProjection);
model.setMapProjection(mapProjection);
Expand All @@ -243,7 +244,7 @@ function useCoordinateState(
const validationResult = model.validationResult;
onSelect(validationResult);
}
}, [model, intl, inputProp, selectedProjection, mapProjection, onSelect]);
}, [model, intl, numberParser, inputProp, selectedProjection, mapProjection, onSelect]);

const { rawInput, validationResult } = useReactiveSnapshot(() => {
return {
Expand All @@ -265,19 +266,25 @@ class StateModel {
#selectedProjection: Reactive<ProjectionItem>;
#mapProjection = reactive<Projection | undefined>();
#inputProp = reactive<Coordinate | undefined>();
#numberParser: Reactive<NumberParserService>;

#rawInput = reactive("");
#validationResult = computed(() => {
return parseCoordinates(
this.#rawInput.value,
this.#intl.value.locale,
this.#numberParser.value,
this.#selectedProjection.value.value
);
});

constructor(intl: PackageIntl, selectedProjection: ProjectionItem) {
constructor(
intl: PackageIntl,
selectedProjection: ProjectionItem,
numberParser: NumberParserService
) {
this.#intl = reactive(intl);
this.#selectedProjection = reactive(selectedProjection);
this.#numberParser = reactive(numberParser);
}

get inputProp() {
Expand All @@ -296,8 +303,9 @@ class StateModel {
return this.#selectedProjection.value;
}

setIntl(value: PackageIntl) {
this.#intl.value = value;
setI18n(intl: PackageIntl, numberParser: NumberParserService) {
this.#intl.value = intl;
this.#numberParser.value = numberParser;
}

setText(text: string) {
Expand Down
Loading

0 comments on commit 5efd5b3

Please sign in to comment.