diff --git a/jest.config.js b/jest.config.js index 38623dcd40..f167aac791 100644 --- a/jest.config.js +++ b/jest.config.js @@ -20,7 +20,7 @@ module.exports = { '/dist/' ], transformIgnorePatterns: [ - 'node_modules/(?!(ol|@camptocamp/inkmap|@terrestris/react-util|d3-selection)/)' + 'node_modules/(?!(ol|@camptocamp/inkmap|@terrestris/react-util|d3-selection|color-space|color-*[a-z]*)|(rc-*[a-z]*)/)' ], setupFiles: [ '/jest/__mocks__/matchMediaMock.js' diff --git a/jest/setup.js b/jest/setup.js index b00302254a..57ba4306ad 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -1,12 +1,13 @@ -import Enzyme from 'enzyme'; -import Adapter from '@cfaester/enzyme-adapter-react-18'; import 'whatwg-fetch'; import 'jest-canvas-mock'; import '@testing-library/jest-dom'; import 'regenerator-runtime/runtime'; + +import Adapter from '@cfaester/enzyme-adapter-react-18'; +import Enzyme from 'enzyme'; import { - TextEncoder, - TextDecoder + TextDecoder, + TextEncoder } from 'util'; Object.assign(global, { diff --git a/package-lock.json b/package-lock.json index 340d3f58bc..8e14c0344e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "@terrestris/eslint-config-typescript": "^5.0.0", "@terrestris/ol-util": "^14.0.0", "@testing-library/dom": "^9.3.3", - "@testing-library/jest-dom": "^6.1.4", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.5.1", "@types/enzyme": "^3.10.15", diff --git a/package.json b/package.json index 7d4da6fdd1..4172aa52b3 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "@terrestris/eslint-config-typescript": "^5.0.0", "@terrestris/ol-util": "^14.0.0", "@testing-library/dom": "^9.3.3", - "@testing-library/jest-dom": "^6.1.4", + "@testing-library/jest-dom": "^6.4.2", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.5.1", "@types/enzyme": "^3.10.15", diff --git a/src/Button/CopyButton/CopyButton.tsx b/src/Button/CopyButton/CopyButton.tsx index 1257068ee9..24111f30c1 100644 --- a/src/Button/CopyButton/CopyButton.tsx +++ b/src/Button/CopyButton/CopyButton.tsx @@ -1,7 +1,6 @@ import AnimateUtil from '@terrestris/ol-util/dist/AnimateUtil/AnimateUtil'; import useMap from '@terrestris/react-util/dist/Hooks/useMap/useMap'; import { DigitizeUtil } from '@terrestris/react-util/dist/Util/DigitizeUtil'; -import OlGeometry from 'ol/geom/Geometry'; import { SelectEvent as OlSelectEvent } from 'ol/interaction/Select'; import OlVectorLayer from 'ol/layer/Vector'; import OlVectorSource from 'ol/source/Vector'; @@ -19,7 +18,7 @@ interface OwnProps { * The vector layer which will be used for digitize features. * The standard digitizeLayer can be retrieved via `DigitizeUtil.getDigitizeLayer(map)`. */ - digitizeLayer?: OlVectorLayer>; + digitizeLayer?: OlVectorLayer; /** * Listener function for the 'select' event of the ol.interaction.Select * if in `Copy` mode. @@ -42,7 +41,7 @@ const CopyButton: React.FC = ({ ...passThroughProps }) => { - const [layers, setLayers] = useState<[OlVectorLayer>]|null>(null); + const [layers, setLayers] = useState<[OlVectorLayer]|null>(null); const map = useMap(); diff --git a/src/Button/DeleteButton/DeleteButton.tsx b/src/Button/DeleteButton/DeleteButton.tsx index 605d83ac02..712b1ed396 100644 --- a/src/Button/DeleteButton/DeleteButton.tsx +++ b/src/Button/DeleteButton/DeleteButton.tsx @@ -1,6 +1,5 @@ import useMap from '@terrestris/react-util/dist/Hooks/useMap/useMap'; import { DigitizeUtil } from '@terrestris/react-util/dist/Util/DigitizeUtil'; -import OlGeometry from 'ol/geom/Geometry'; import { SelectEvent as OlSelectEvent } from 'ol/interaction/Select'; import OlVectorLayer from 'ol/layer/Vector'; import OlVectorSource from 'ol/source/Vector'; @@ -15,7 +14,7 @@ interface OwnProps { * The vector layer which will be used for digitize features. * The standard digitizeLayer can be retrieved via `DigitizeUtil.getDigitizeLayer(map)`. */ - digitizeLayer?: OlVectorLayer>; + digitizeLayer?: OlVectorLayer; /** * Listener function for the 'select' event of the ol.interaction.Select * if in `Delete` mode. @@ -39,7 +38,7 @@ export const DeleteButton: React.FC = ({ onFeatureRemove, ...passThroughProps }) => { - const [layers, setLayers] = useState<[OlVectorLayer>]|null>(null); + const [layers, setLayers] = useState<[OlVectorLayer]|null>(null); const map = useMap(); diff --git a/src/Button/DrawButton/DrawButton.spec.tsx b/src/Button/DrawButton/DrawButton.spec.tsx index 7f2c544f01..9387db3651 100644 --- a/src/Button/DrawButton/DrawButton.spec.tsx +++ b/src/Button/DrawButton/DrawButton.spec.tsx @@ -14,7 +14,7 @@ import DrawButton from './DrawButton'; describe('', () => { - let map; + let map: OlMap; beforeEach(() => { map = new OlMap({ diff --git a/src/Button/DrawButton/DrawButton.tsx b/src/Button/DrawButton/DrawButton.tsx index 7b352f6cd9..4d4b32a33e 100644 --- a/src/Button/DrawButton/DrawButton.tsx +++ b/src/Button/DrawButton/DrawButton.tsx @@ -58,7 +58,7 @@ interface OwnProps { * The vector layer which will be used for digitize features. * The standard digitizeLayer can be retrieved via `DigitizeUtil.getDigitizeLayer(map)`. */ - digitizeLayer?: OlVectorLayer>; + digitizeLayer?: OlVectorLayer; /** * Title for modal used for input of labels for digitize features. */ @@ -112,10 +112,10 @@ const DrawButton: React.FC = ({ }) => { const [drawInteraction, setDrawInteraction] = useState(); - const [layer, setLayer] = useState> | null>(null); + const [layer, setLayer] = useState | null>(null); /** - * Currently drawn feature which should be represent as label or postit. + * Currently drawn feature which should be represented as label or post-it. */ const [digitizeTextFeature, setDigitizeTextFeature] = useState | null>(null); diff --git a/src/Button/GeoLocationButton/GeoLocationButton.spec.tsx b/src/Button/GeoLocationButton/GeoLocationButton.spec.tsx index 222da947a7..04e741ce4d 100644 --- a/src/Button/GeoLocationButton/GeoLocationButton.spec.tsx +++ b/src/Button/GeoLocationButton/GeoLocationButton.spec.tsx @@ -7,13 +7,10 @@ import { render, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; -import TestUtil from '../../Util/TestUtil'; import GeoLocationButton from './GeoLocationButton'; describe('', () => { - let map; - beforeAll(() => { enableGeolocationMock(); }); @@ -22,10 +19,6 @@ describe('', () => { disableGeolocationMock(); }); - beforeEach(() => { - map = TestUtil.createMap(); - }); - describe('#Basics', () => { it('is defined', () => { diff --git a/src/Button/MeasureButton/MeasureButton.spec.tsx b/src/Button/MeasureButton/MeasureButton.spec.tsx index 573682a135..ce8f8689bb 100644 --- a/src/Button/MeasureButton/MeasureButton.spec.tsx +++ b/src/Button/MeasureButton/MeasureButton.spec.tsx @@ -1,19 +1,21 @@ import MeasureUtil from '@terrestris/ol-util/dist/MeasureUtil/MeasureUtil'; +import {EventTargetLike} from 'ol/events/Target'; import OlFeature from 'ol/Feature'; import OlGeomLineString from 'ol/geom/LineString'; import OlGeomPoint from 'ol/geom/Point'; import OlGeomPolygon from 'ol/geom/Polygon'; -import OlInteractionDraw from 'ol/interaction/Draw'; +import OlInteractionDraw, {DrawEvent} from 'ol/interaction/Draw'; import OlLayerVector from 'ol/layer/Vector'; +import OlMap from 'ol/Map'; import * as OlObservable from 'ol/Observable'; import OlOverlay from 'ol/Overlay'; -import TestUtil from '../../Util/TestUtil'; -import MeasureButton from './MeasureButton'; +import TestUtil, {Wrapper} from '../../Util/TestUtil'; +import MeasureButton, {MeasureButtonProps} from './MeasureButton'; describe('', () => { - let map; + let map: OlMap; beforeEach(() => { map = TestUtil.createMap(); @@ -57,24 +59,25 @@ describe('', () => { pressed: true }); - expect(wrapper.props().measureLayerName).toBe('measureLayerName'); - expect(wrapper.props().fillColor).toBe('#ff0000'); - expect(wrapper.props().strokeColor).toBe('#0000ff'); - expect(wrapper.props().showMeasureInfoOnClickedPoints).toBe(true); - expect(wrapper.props().clickToDrawText).toBe('Click to draw'); - expect(wrapper.props().continuePolygonMsg).toBe('Continue draw polygon'); - expect(wrapper.props().continueLineMsg).toBe('Continue draw line'); - expect(wrapper.props().continueAngleMsg).toBe('Continue draw angle'); - expect(wrapper.props().decimalPlacesInTooltips).toBe(5); - expect(wrapper.props().measureTooltipCssClasses).toEqual({ + const props: MeasureButtonProps = wrapper.props() as MeasureButtonProps; + expect(props.measureLayerName).toBe('measureLayerName'); + expect(props.fillColor).toBe('#ff0000'); + expect(props.strokeColor).toBe('#0000ff'); + expect(props.showMeasureInfoOnClickedPoints).toBe(true); + expect(props.clickToDrawText).toBe('Click to draw'); + expect(props.continuePolygonMsg).toBe('Continue draw polygon'); + expect(props.continueLineMsg).toBe('Continue draw line'); + expect(props.continueAngleMsg).toBe('Continue draw angle'); + expect(props.decimalPlacesInTooltips).toBe(5); + expect(props.measureTooltipCssClasses).toEqual({ tooltip: 'tooltip-cls', tooltipDynamic: 'dynamic-tooltip-cls', tooltipStatic: 'static-tooltip-cls' }); - expect(wrapper.props().pressed).toBe(true); + expect(props.pressed).toBe(true); - expect(wrapper.props().measureTooltipCssClasses).toBeInstanceOf(Object); - expect(wrapper.find('button', {pressed: true}).length).toBe(1); + expect(props.measureTooltipCssClasses).toBeInstanceOf(Object); + expect(wrapper.find('button').length).toBe(1); }); }); @@ -111,12 +114,12 @@ describe('', () => { pressed: true }); - const instance = wrapper.instance(); + const instance: MeasureButton = wrapper.instance() as MeasureButton; - expect(instance._drawInteraction.getActive()).toBe(true); - expect(instance._eventKeys.drawstart).toBeDefined(); - expect(instance._eventKeys.drawend).toBeDefined(); - expect(instance._eventKeys.pointermove).toBeDefined(); + expect(instance._drawInteraction?.getActive()).toBe(true); + expect(instance._eventKeys?.drawstart).toBeDefined(); + expect(instance._eventKeys?.drawend).toBeDefined(); + expect(instance._eventKeys?.pointermove).toBeDefined(); }); }); @@ -129,7 +132,7 @@ describe('', () => { measureType: 'line' }); - const instance = wrapper.instance(); + const instance: MeasureButton = wrapper.instance() as MeasureButton; expect(instance._measureLayer).toBeDefined(); expect(instance._measureLayer).toBeInstanceOf(OlLayerVector); @@ -145,11 +148,11 @@ describe('', () => { pressed: true }); - const instance = wrapper.instance(); + const instance: MeasureButton = wrapper.instance() as MeasureButton; expect(instance._drawInteraction).toBeDefined(); expect(instance._drawInteraction).toBeInstanceOf(OlInteractionDraw); - expect(instance._drawInteraction.getActive()).toBeTruthy(); + expect(instance._drawInteraction?.getActive()).toBeTruthy(); }); }); @@ -162,19 +165,19 @@ describe('', () => { pressed: true }); - const instance = wrapper.instance(); + const instance: MeasureButton = wrapper.instance() as MeasureButton; const removeHelpTooltipSpy = jest.spyOn(instance, 'removeHelpTooltip'); const removeMeasureTooltipSpy = jest.spyOn(instance, 'removeMeasureTooltip'); const createHelpTooltipSpy = jest.spyOn(instance, 'createHelpTooltip'); const createMeasureTooltipSpy = jest.spyOn(instance, 'createMeasureTooltip'); - instance._drawInteraction.setActive(false); + instance._drawInteraction?.setActive(false); expect(removeHelpTooltipSpy).toHaveBeenCalledTimes(1); expect(removeMeasureTooltipSpy).toHaveBeenCalledTimes(1); - instance._drawInteraction.setActive(true); + instance._drawInteraction?.setActive(true); expect(createHelpTooltipSpy).toHaveBeenCalledTimes(1); expect(createMeasureTooltipSpy).toHaveBeenCalledTimes(1); @@ -188,9 +191,9 @@ describe('', () => { describe('#drawStart', () => { - let mockEvt; - let wrapper; - let instance; + let mockEvt: Partial; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { mockEvt = { @@ -203,17 +206,17 @@ describe('', () => { measureType: 'line', showMeasureInfoOnClickedPoints: true }); - wrapper.instance()._measureLayer.getSource().addFeature(mockEvt.feature); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; + instance._measureLayer?.getSource()?.addFeature(mockEvt.feature!); }); it('sets the feature', () => { - instance.onDrawStart(mockEvt); + instance.onDrawStart(mockEvt as DrawEvent); expect(instance._feature).toBe(mockEvt.feature); }); it('sets event key for click', () => { - instance.onDrawStart(mockEvt); + instance.onDrawStart(mockEvt as DrawEvent); expect(instance._eventKeys.click).toBeDefined(); }); @@ -221,9 +224,9 @@ describe('', () => { const cleanupTooltipsSpy = jest.spyOn(instance, 'cleanupTooltips'); const createMeasureTooltipSpy = jest.spyOn(instance, 'createMeasureTooltip'); const createHelpTooltipSpy = jest.spyOn(instance, 'createHelpTooltip'); - const clearSpy = jest.spyOn(wrapper.instance()._measureLayer.getSource(), 'clear'); + const clearSpy = jest.spyOn(instance._measureLayer?.getSource()!, 'clear'); - instance.onDrawStart(mockEvt); + instance.onDrawStart(mockEvt as DrawEvent); expect(cleanupTooltipsSpy).toHaveBeenCalledTimes(1); expect(createMeasureTooltipSpy).toHaveBeenCalledTimes(1); @@ -239,9 +242,9 @@ describe('', () => { describe('#drawEnd', () => { - let wrapper; - let instance; - let mockEvt; + let mockEvt: Partial; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { @@ -249,7 +252,7 @@ describe('', () => { measureType: 'line', showMeasureInfoOnClickedPoints: true }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; mockEvt = { feature: new OlFeature({ geometry: new OlGeomPoint([0, 0]) @@ -259,11 +262,17 @@ describe('', () => { it ('unsets click event key', () => { - instance._eventKeys.click = jest.fn(); + instance._eventKeys.click = { + target: { + removeEventListener: jest.fn() + } as unknown as EventTargetLike, + listener: jest.fn(), + type: 'click' + }; const unByKeySpy = jest.spyOn(OlObservable, 'unByKey'); - instance.onDrawEnd(mockEvt); + instance.onDrawEnd(mockEvt as DrawEvent); expect(unByKeySpy).toHaveBeenCalledTimes(1); @@ -275,7 +284,7 @@ describe('', () => { showMeasureInfoOnClickedPoints: true }); const removeMeasureTooltipSpy = jest.spyOn(instance, 'removeMeasureTooltip'); - instance.onDrawEnd(mockEvt); + instance.onDrawEnd(mockEvt as DrawEvent); expect(removeMeasureTooltipSpy).toHaveBeenCalledTimes(1); removeMeasureTooltipSpy.mockRestore(); }); @@ -286,16 +295,16 @@ describe('', () => { }); instance.createMeasureTooltip(); - instance.onDrawEnd(mockEvt); + instance.onDrawEnd(mockEvt as DrawEvent); const expectedClassName = 'react-geo-measure-tooltip react-geo-measure-tooltip-static'; const expectedOffset = [0, -7]; - expect(instance._measureTooltipElement.className).toContain(expectedClassName); - expect(instance._measureTooltip.getOffset()).toEqual(expectedOffset); + expect(instance._measureTooltipElement?.className).toContain(expectedClassName); + expect(instance._measureTooltip?.getOffset()).toEqual(expectedOffset); }); it ('unsets the feature', () => { - instance.onDrawEnd(mockEvt); + instance.onDrawEnd(mockEvt as DrawEvent); expect(instance._feature).toBeNull(); }); @@ -304,7 +313,7 @@ describe('', () => { showMeasureInfoOnClickedPoints: true }); const createMeasureTooltipSpy = jest.spyOn(instance, 'createMeasureTooltip'); - instance.onDrawEnd(mockEvt); + instance.onDrawEnd(mockEvt as DrawEvent); expect(createMeasureTooltipSpy).toHaveBeenCalledTimes(1); createMeasureTooltipSpy.mockRestore(); }); @@ -312,17 +321,17 @@ describe('', () => { describe('#addMeasureStopTooltip', () => { - let wrapper; - let instance; - let coordinate; - let mockLineFeat; + let wrapper: Wrapper; + let instance: MeasureButton; + let coordinate: number[]; + let mockLineFeat: OlFeature; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; coordinate = [100, 100]; mockLineFeat = new OlFeature({ geometry: new OlGeomLineString([[0, 0], [0, 100]]) @@ -337,7 +346,8 @@ describe('', () => { expect(instance._feature).toBeDefined(); expect(instance._feature.getGeometry()).toBeDefined(); - const value = MeasureUtil.formatLength(instance._feature.getGeometry(), map, 2); + const geometry = instance._feature?.getGeometry() as OlGeomLineString; + const value = MeasureUtil.formatLength(geometry, map, 2); expect(value).toBe('99.89 m'); }); @@ -364,7 +374,8 @@ describe('', () => { expect(instance._feature).toBeDefined(); expect(instance._feature.getGeometry()).toBeDefined(); - const value = MeasureUtil.formatArea(instance._feature.getGeometry(), map, 2); + const geometry = instance._feature?.getGeometry() as OlGeomPolygon; + const value = MeasureUtil.formatArea(geometry, map, 2); expect(value).toBe('99.78 m2'); }); @@ -377,7 +388,8 @@ describe('', () => { instance._feature = mockLineFeat; instance.addMeasureStopTooltip(coordinate); - const value = MeasureUtil.formatLength(instance._feature.getGeometry(), map, 2); + const geometry = instance._feature?.getGeometry() as OlGeomLineString; + const value = MeasureUtil.formatLength(geometry, map, 2); expect(parseInt(value, 10)).toBeGreaterThan(10); const overlays = map.getOverlays(); @@ -386,7 +398,7 @@ describe('', () => { const overlay = overlays.getArray()[0]; const offset = overlay.getOffset(); const positioning = overlay.getPositioning(); - const className = overlay.getElement().className; + const className = overlay.getElement()?.className; expect(offset).toEqual([0, -15]); expect(positioning).toBe('bottom-center'); @@ -400,19 +412,21 @@ describe('', () => { describe('#createMeasureTooltip', () => { - let wrapper; - let instance; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; }); it('returns undefined if measureTooltipElement already set', () => { - instance._measureTooltipElement = 'some value'; + const div = document.createElement('div'); + div.innerHTML = 'some value'; + instance._measureTooltipElement = div; const expectedOutput = instance.createMeasureTooltip(); expect(expectedOutput).toBeUndefined(); }); @@ -427,7 +441,7 @@ describe('', () => { const overlay = overlays.getArray()[0]; const offset = overlay.getOffset(); const positioning = overlay.getPositioning(); - const className = overlay.getElement().className; + const className = overlay.getElement()?.className; expect(offset).toEqual([0, -15]); expect(positioning).toBe('bottom-center'); @@ -437,19 +451,21 @@ describe('', () => { describe('#createHelpTooltip', () => { - let wrapper; - let instance; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; }); it('returns undefined if _helpTooltipElement already set', () => { - instance._helpTooltipElement = 'some value'; + const div = document.createElement('div'); + div.innerHTML = 'some value'; + instance._helpTooltipElement = div; const expectedOutput = instance.createHelpTooltip(); expect(expectedOutput).toBeUndefined(); }); @@ -464,7 +480,7 @@ describe('', () => { const overlay = overlays.getArray()[0]; const offset = overlay.getOffset(); const positioning = overlay.getPositioning(); - const className = overlay.getElement().className; + const className = overlay.getElement()?.className; expect(offset).toEqual([15, 0]); expect(positioning).toBe('center-left'); @@ -474,15 +490,15 @@ describe('', () => { describe('#removeHelpTooltip', () => { - let wrapper; - let instance; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; }); it ('removes help tooltip overlay from the map', () => { @@ -511,15 +527,15 @@ describe('', () => { describe('#removeMeasureTooltip', () => { - let wrapper; - let instance; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; }); it ('removes measure tooltip overlay from the map', () => { @@ -548,19 +564,19 @@ describe('', () => { describe('#cleanupTooltips', () => { - let wrapper; - let instance; - let tooltipDiv1; - let tooltipDiv2; - let tooltip1; - let tooltip2; + let wrapper: Wrapper; + let instance: MeasureButton; + let tooltipDiv1: HTMLDivElement; + let tooltipDiv2: HTMLDivElement; + let tooltip1: OlOverlay; + let tooltip2: OlOverlay; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; tooltipDiv1 = document.createElement('div'); tooltipDiv2 = document.createElement('div'); @@ -599,40 +615,62 @@ describe('', () => { describe('#cleanup', () => { - let wrapper; - let instance; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; }); it ('sets draw interaction state to false', () => { instance.createDrawInteraction(); - instance._drawInteraction.setActive(true); + instance._drawInteraction?.setActive(true); instance.cleanup(); - expect(instance._drawInteraction.getActive()).not.toBeTruthy(); + expect(instance._drawInteraction?.getActive()).not.toBeTruthy(); }); it ('unbinds all event keys', () => { instance._eventKeys = { - drawstart: jest.fn(), - drawend: jest.fn(), - pointermove: jest.fn(), - click: jest.fn(), + drawstart: { + target: {} as EventTargetLike, + listener: jest.fn(), + type: 'click' + }, + drawend: { + target: {} as EventTargetLike, + listener: jest.fn(), + type: 'click' + }, + pointermove: { + target: {} as EventTargetLike, + listener: jest.fn(), + type: 'click' + }, + click: { + target: {} as EventTargetLike, + listener: jest.fn(), + type: 'click' + }, + change: { + target: {} as EventTargetLike, + listener: jest.fn(), + type: 'click' + } }; + // @ts-ignore OlObservable.unByKey = jest.fn(); instance.cleanup(); - expect(OlObservable.unByKey).toHaveBeenCalledTimes(4); + expect(OlObservable.unByKey).toHaveBeenCalledTimes(5); }); it ('calls cleanupTooltips method', () => { @@ -651,47 +689,44 @@ describe('', () => { const mockFeat = new OlFeature(); - instance._measureLayer.getSource().addFeature(mockFeat); - expect(instance._measureLayer.getSource().getFeatures().length).toBe(1); + instance._measureLayer?.getSource()?.addFeature(mockFeat); + expect(instance._measureLayer?.getSource()?.getFeatures().length).toBe(1); instance.cleanup(); - expect(instance._measureLayer.getSource().getFeatures().length).toBe(0); + expect(instance._measureLayer?.getSource()?.getFeatures().length).toBe(0); }); }); describe('#updateMeasureTooltip', () => { - let wrapper; - let instance; - let geometry; + let wrapper: Wrapper; + let instance: MeasureButton; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); - geometry = new OlGeomPoint([100, 100]); + instance = wrapper.instance() as MeasureButton; }); it ('returns undefined if measure and tooltip elements are not set', () => { - const expectedOutput = instance.updateMeasureTooltip(geometry); + const expectedOutput = instance.updateMeasureTooltip(); expect(expectedOutput).toBeUndefined(); }); it ('sets correct tooltip position for line measurements', () => { - const mockLineFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomLineString([[0, 0], [0, 100]]) }); - instance._feature = mockLineFeat; instance._measureTooltipElement = document.createElement('div'); instance._measureTooltip = new OlOverlay({ element: instance._measureTooltipElement }); - instance.updateMeasureTooltip(geometry); + instance.updateMeasureTooltip(); expect(instance._measureTooltipElement.innerHTML).toBe('99.89 m'); expect(instance._measureTooltip.getPosition()).toEqual([0, 100]); @@ -706,12 +741,10 @@ describe('', () => { [10, 0], [0, 0] ]; - const mockPolyFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomPolygon([polyCoords]) }); - instance._feature = mockPolyFeat; - wrapper.setProps({ measureType: 'polygon' }); @@ -721,7 +754,7 @@ describe('', () => { element: instance._measureTooltipElement }); - instance.updateMeasureTooltip(geometry); + instance.updateMeasureTooltip(); expect(instance._measureTooltipElement.innerHTML).toBe('99.78 m2'); // Interior point as XYM coordinate, where M is the length of the horizontal @@ -730,10 +763,9 @@ describe('', () => { }); it ('sets correct tooltip position for angle measurements', () => { - const mockLineFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomLineString([[0, 0], [0, 100]]) }); - instance._feature = mockLineFeat; wrapper.setProps({ measureType: 'angle' @@ -744,7 +776,7 @@ describe('', () => { element: instance._measureTooltipElement }); - instance.updateMeasureTooltip(geometry); + instance.updateMeasureTooltip(); expect(instance._measureTooltipElement.innerHTML).toBe('0°'); expect(instance._measureTooltip.getPosition()).toEqual([0, 100]); @@ -753,16 +785,16 @@ describe('', () => { describe('#updateHelpTooltip', () => { - let wrapper; - let instance; - let geometry; + let wrapper: Wrapper; + let instance: MeasureButton; + let geometry: OlGeomPoint; beforeEach(() => { wrapper = TestUtil.mountComponent(MeasureButton, { map: map, measureType: 'line' }); - instance = wrapper.instance(); + instance = wrapper.instance() as MeasureButton; geometry = new OlGeomPoint([100, 100]); }); @@ -772,10 +804,9 @@ describe('', () => { }); it ('sets correct help message and position for line measurements', () => { - const mockLineFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomLineString([[0, 0], [0, 100]]) }); - instance._feature = mockLineFeat; instance._helpTooltipElement = document.createElement('div'); instance._helpTooltip = new OlOverlay({ @@ -797,12 +828,10 @@ describe('', () => { [10, 0], [0, 0] ]; - const mockPolyFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomPolygon([polyCoords]) }); - instance._feature = mockPolyFeat; - wrapper.setProps({ measureType: 'polygon' }); @@ -819,10 +848,9 @@ describe('', () => { }); it ('sets correct help message and position for angle measurements', () => { - const mockLineFeat = new OlFeature({ + instance._feature = new OlFeature({ geometry: new OlGeomLineString([[0, 0], [0, 100]]) }); - instance._feature = mockLineFeat; wrapper.setProps({ measureType: 'angle' diff --git a/src/Button/MeasureButton/MeasureButton.tsx b/src/Button/MeasureButton/MeasureButton.tsx index 9d79739111..54f28cb920 100644 --- a/src/Button/MeasureButton/MeasureButton.tsx +++ b/src/Button/MeasureButton/MeasureButton.tsx @@ -6,10 +6,10 @@ import _isNil from 'lodash/isNil'; import OlCollection from 'ol/Collection'; import { EventsKey } from 'ol/events'; import OlFeature from 'ol/Feature'; +import OlGeomCircle from 'ol/geom/Circle'; import OlGeometry, { Type } from 'ol/geom/Geometry'; import OlGeomLineString from 'ol/geom/LineString'; import OlMultiLineString from 'ol/geom/MultiLineString'; -import OlGeomCircle from 'ol/geom/Circle'; import OlMultiPolygon from 'ol/geom/MultiPolygon'; import OlGeomPolygon from 'ol/geom/Polygon'; import OlInteractionDraw, { DrawEvent } from 'ol/interaction/Draw'; @@ -125,6 +125,8 @@ interface OwnProps { export type MeasureType = 'line' | 'polygon' | 'angle' | 'circle'; export type MeasureButtonProps = OwnProps & Partial; +export type EventName = 'drawstart' | 'drawend' | 'pointermove' | 'click' | 'change'; +export type EventsKeyType = {[K in EventName]: EventsKey | undefined}; /** * The MeasureButton. @@ -231,7 +233,7 @@ class MeasureButton extends React.Component { * * @private */ - _eventKeys: {[K in 'drawstart'|'drawend'|'pointermove'|'click'|'change']: EventsKey|undefined} = { + _eventKeys: EventsKeyType = { drawstart: undefined, drawend: undefined, pointermove: undefined, @@ -244,7 +246,7 @@ class MeasureButton extends React.Component { * * @private */ - _measureLayer: OlLayerVector> | null = null; + _measureLayer: OlLayerVector | null = null; /** * The draw interaction used to draw the geometries to measure. @@ -336,7 +338,7 @@ class MeasureButton extends React.Component { map } = this.props; - let measureLayer = MapUtil.getLayerByName(map, measureLayerName) as OlLayerVector>; + let measureLayer = MapUtil.getLayerByName(map, measureLayerName) as OlLayerVector; if (!measureLayer) { measureLayer = new OlLayerVector({ @@ -767,8 +769,9 @@ class MeasureButton extends React.Component { } Object.keys(this._eventKeys).forEach(key => { - if (this._eventKeys[key]) { - unByKey(this._eventKeys[key]); + const eventKey = this._eventKeys[key as EventName] as EventsKey; + if (eventKey) { + unByKey(eventKey); } }); diff --git a/src/Button/ModifyButton/ModifyButton.tsx b/src/Button/ModifyButton/ModifyButton.tsx index f6390d3951..a8bcd1e544 100644 --- a/src/Button/ModifyButton/ModifyButton.tsx +++ b/src/Button/ModifyButton/ModifyButton.tsx @@ -40,7 +40,7 @@ interface OwnProps { * The vector layer which will be used for digitize features. * The standard digitizeLayer can be retrieved via `DigitizeUtil.getDigitizeLayer(map)`. */ - digitizeLayer?: OlVectorLayer>; + digitizeLayer?: OlVectorLayer; /** * Listener function for the 'modifystart' event of an ol.interaction.Modify. * See https://openlayers.org/en/latest/apidoc/module-ol_interaction_Modify-ModifyEvent.html @@ -60,7 +60,7 @@ interface OwnProps { */ onTranslateStart?: (event: TranslateEvent) => void; /** - * Listener function for the 'translateend' event of an ol.interaction.Translate. + * Listener function for the 'qtranslateend' event of an ol.interaction.Translate. * See https://openlayers.org/en/latest/apidoc/module-ol_interaction_Translate-TranslateEvent.html * for more information. */ @@ -132,7 +132,7 @@ export const ModifyButton: React.FC = ({ editLabel = true, ...passThroughProps }) => { - const [layers, setLayers] = useState<[OlVectorLayer>]|null>(null); + const [layers, setLayers] = useState<[OlVectorLayer]|null>(null); const [modifyInteraction, setModifyInteraction] = useState(null); const [translateInteraction, setTranslateInteraction] = useState(null); const [features, setFeatures] = useState>|null>(null); diff --git a/src/Button/SelectFeaturesButton/SelectFeaturesButton.spec.tsx b/src/Button/SelectFeaturesButton/SelectFeaturesButton.spec.tsx index 94f3fa982d..490ea60ce5 100644 --- a/src/Button/SelectFeaturesButton/SelectFeaturesButton.spec.tsx +++ b/src/Button/SelectFeaturesButton/SelectFeaturesButton.spec.tsx @@ -17,7 +17,7 @@ describe('', () => { const coord = [829729, 6708850]; let map: OlMap; - let layer: OlVectorLayer>; + let layer: OlVectorLayer; let feature: OlFeature; beforeEach(() => { diff --git a/src/Button/SelectFeaturesButton/SelectFeaturesButton.tsx b/src/Button/SelectFeaturesButton/SelectFeaturesButton.tsx index 28bb7ba9e5..2babdb95dc 100644 --- a/src/Button/SelectFeaturesButton/SelectFeaturesButton.tsx +++ b/src/Button/SelectFeaturesButton/SelectFeaturesButton.tsx @@ -42,7 +42,7 @@ interface OwnProps { /** * Array of layers the SelectFeaturesButton should operate on. */ - layers: OlVectorLayer>[]; + layers: OlVectorLayer[]; /** * Hit tolerance of the select action. Default: 5 */ diff --git a/src/Button/SimpleButton/SimpleButton.spec.tsx b/src/Button/SimpleButton/SimpleButton.spec.tsx index e151173b4f..5290da26a2 100644 --- a/src/Button/SimpleButton/SimpleButton.spec.tsx +++ b/src/Button/SimpleButton/SimpleButton.spec.tsx @@ -1,5 +1,5 @@ import TestUtil from '../../Util/TestUtil'; -import SimpleButton from './SimpleButton'; +import SimpleButton, {SimpleButtonProps} from './SimpleButton'; describe('', () => { it('is defined', () => { @@ -21,15 +21,16 @@ describe('', () => { disabled: true }); - expect(wrapper.props().type).toBe('secondary'); - expect(wrapper.props().shape).toBe('circle'); - expect(wrapper.props().size).toBe('small'); - expect(wrapper.props().disabled).toBe(true); + const props = wrapper.props() as SimpleButtonProps; + expect(props.type).toBe('secondary'); + expect(props.shape).toBe('circle'); + expect(props.size).toBe('small'); + expect(props.disabled).toBe(true); expect(wrapper.find('button.ant-btn-secondary').length).toBe(1); expect(wrapper.find('button.ant-btn-circle').length).toBe(1); expect(wrapper.find('button.ant-btn-sm').length).toBe(1); - expect(wrapper.find('button', {disabled: true}).length).toBe(1); + expect(wrapper.find('button').length).toBe(1); }); it('calls a given click callback method onClick', () => { diff --git a/src/Button/ZoomButton/ZoomButton.spec.tsx b/src/Button/ZoomButton/ZoomButton.spec.tsx index 477b747f07..c8647331b5 100644 --- a/src/Button/ZoomButton/ZoomButton.spec.tsx +++ b/src/Button/ZoomButton/ZoomButton.spec.tsx @@ -1,6 +1,7 @@ import { actSetTimeout } from '@terrestris/react-util/dist/Util/rtlTestUtils'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import _isNil from 'lodash/isNil'; import OlMap from 'ol/Map'; import * as React from 'react'; @@ -9,7 +10,7 @@ import ZoomButton from './ZoomButton'; describe('', () => { - let map; + let map: OlMap; beforeEach(() => { map = TestUtil.createMap(); @@ -30,12 +31,14 @@ describe('', () => { ); const initialZoom = map.getView().getZoom(); - const button = screen.getByText('Zoom test'); - await userEvent.click(button); + if (!_isNil(initialZoom)) { + const button = screen.getByText('Zoom test'); + await userEvent.click(button); - await actSetTimeout(300); - const newZoom = map.getView().getZoom(); - expect(newZoom).toBe(initialZoom + 1); + await actSetTimeout(300); + const newZoom = map.getView().getZoom(); + expect(newZoom).toBe(initialZoom + 1); + } }); it('can be configured to zoom out', async () => { @@ -44,12 +47,14 @@ describe('', () => { ); const initialZoom = map.getView().getZoom(); - const button = screen.getByText('Zoom test'); - await userEvent.click(button); + if (!_isNil(initialZoom)) { + const button = screen.getByText('Zoom test'); + await userEvent.click(button); - await actSetTimeout(300); - const newZoom = map.getView().getZoom(); - expect(newZoom).toBe(initialZoom - 1); + await actSetTimeout(300); + const newZoom = map.getView().getZoom(); + expect(newZoom).toBe(initialZoom - 1); + } }); it('does not belch when map has no view', () => { @@ -76,7 +81,7 @@ describe('', () => { await userEvent.click(button); await userEvent.click(button); - expect(view.cancelAnimations.mock.calls.length).toBe(2); + expect((view.cancelAnimations as jest.Mock).mock.calls.length).toBe(2); }); }); diff --git a/src/Button/ZoomToExtentButton/ZoomToExtentButton.spec.tsx b/src/Button/ZoomToExtentButton/ZoomToExtentButton.spec.tsx index db02c42c78..e0aea4a115 100644 --- a/src/Button/ZoomToExtentButton/ZoomToExtentButton.spec.tsx +++ b/src/Button/ZoomToExtentButton/ZoomToExtentButton.spec.tsx @@ -1,12 +1,13 @@ import { containsExtent,getCenter } from 'ol/extent'; import OlGeomPolygon from 'ol/geom/Polygon'; +import OlMap from 'ol/Map'; import TestUtil from '../../Util/TestUtil'; import ZoomToExtentButton from '../ZoomToExtentButton/ZoomToExtentButton'; describe('', () => { - let map; + let map: OlMap; const mockGeometry = new OlGeomPolygon([ [[5000, 0], [0, 5000], [5000, 10000], [10000, 5000], [5000, 0]] ]); @@ -36,7 +37,8 @@ describe('', () => { map, extent: mockExtent }); - wrapper.instance().onClick(); + const component = wrapper.instance() as ZoomToExtentButton; + component.onClick(); const promise = new Promise(resolve => { setTimeout(resolve, 1200); @@ -57,7 +59,8 @@ describe('', () => { extent: mockGeometry }); - wrapper.instance().onClick(); + const component = wrapper.instance() as ZoomToExtentButton; + component.onClick(); const promise = new Promise(resolve => { setTimeout(resolve, 1200); @@ -79,7 +82,9 @@ describe('', () => { center: mockExtentCenter, zoom: mockZoom }); - wrapper.instance().onClick(); + + const component = wrapper.instance() as ZoomToExtentButton; + component.onClick(); const promise = new Promise(resolve => { setTimeout(resolve, 1200); diff --git a/src/CircleMenu/CircleMenu.spec.tsx b/src/CircleMenu/CircleMenu.spec.tsx index 2dc60702c2..6381ecd353 100644 --- a/src/CircleMenu/CircleMenu.spec.tsx +++ b/src/CircleMenu/CircleMenu.spec.tsx @@ -31,7 +31,7 @@ describe('', () => { position: [0, 0], animationDuration: animationDuration }); - const instance = wrapper.instance(); + const instance = wrapper.instance() as CircleMenu; const transformationSpy = jest.spyOn(instance, 'applyTransformation'); wrapper.setProps({ @@ -59,7 +59,7 @@ describe('', () => { position: [0, 0], animationDuration: animationDuration }); - const instance = wrapper.instance(); + const instance = wrapper.instance() as CircleMenu; instance.applyTransformation(); diff --git a/src/CircleMenu/CircleMenuItem/CircleMenuItem.spec.tsx b/src/CircleMenu/CircleMenuItem/CircleMenuItem.spec.tsx index 361e71e6e9..a296a63330 100644 --- a/src/CircleMenu/CircleMenuItem/CircleMenuItem.spec.tsx +++ b/src/CircleMenu/CircleMenuItem/CircleMenuItem.spec.tsx @@ -15,7 +15,7 @@ describe('', () => { const wrapper = TestUtil.mountComponent(CircleMenuItem, { children: 'A' }); - const instance = wrapper.instance(); + const instance = wrapper.instance() as CircleMenuItem; const transformationSpy = jest.spyOn(instance, 'applyTransformation'); wrapper.setProps({ @@ -44,7 +44,7 @@ describe('', () => { animationDuration: duration, rotationAngle: rotationAngle }); - const instance = wrapper.instance(); + const instance = wrapper.instance() as CircleMenuItem; expect.assertions(2); diff --git a/src/Container/AddWmsPanel/AddWmsLayerEntry/AddWmsLayerEntry.spec.tsx b/src/Container/AddWmsPanel/AddWmsLayerEntry/AddWmsLayerEntry.spec.tsx index 04a75ac904..6ffe9e6dd9 100644 --- a/src/Container/AddWmsPanel/AddWmsLayerEntry/AddWmsLayerEntry.spec.tsx +++ b/src/Container/AddWmsPanel/AddWmsLayerEntry/AddWmsLayerEntry.spec.tsx @@ -74,9 +74,8 @@ describe('', () => { it('doesn\'t add copyright icon if prop wmsLayer has no attribution', () => { render(); - let icon; expect(() => { - icon = screen.getByLabelText(labelIconAttribution); + screen.getByLabelText(labelIconAttribution); }).toThrowError(); }); diff --git a/src/Container/AddWmsPanel/AddWmsPanel.spec.tsx b/src/Container/AddWmsPanel/AddWmsPanel.spec.tsx index d3241f8d55..ec5e93e495 100644 --- a/src/Container/AddWmsPanel/AddWmsPanel.spec.tsx +++ b/src/Container/AddWmsPanel/AddWmsPanel.spec.tsx @@ -1,8 +1,9 @@ import MapUtil from '@terrestris/ol-util/dist/MapUtil/MapUtil'; import { renderInMapContext } from '@terrestris/react-util/dist/Util/rtlTestUtils'; -import { render, screen, within } from '@testing-library/react'; +import { screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import OlLayerTile from 'ol/layer/Tile'; +import OlMap from 'ol/Map'; import OlSourceTileWMS from 'ol/source/TileWMS'; import * as React from 'react'; @@ -11,7 +12,7 @@ import AddWmsPanel from './AddWmsPanel'; describe('', () => { - let map; + let map: OlMap; const testLayerName = 'OSM-WMS'; const testLayerTitle = 'OSM-WMS - by terrestris'; diff --git a/src/CoordinateInfo/CoordinateInfo.spec.tsx b/src/CoordinateInfo/CoordinateInfo.spec.tsx index e90e127d85..e04e5f8edf 100644 --- a/src/CoordinateInfo/CoordinateInfo.spec.tsx +++ b/src/CoordinateInfo/CoordinateInfo.spec.tsx @@ -1,11 +1,12 @@ import { render } from '@testing-library/react'; +import OlMap from 'ol/Map'; import * as React from 'react'; import CoordinateInfo from '../CoordinateInfo/CoordinateInfo'; import TestUtil from '../Util/TestUtil'; describe('', () => { - let map; + let map: OlMap; beforeEach(() => { map = TestUtil.createMap(); diff --git a/src/CoordinateInfo/CoordinateInfo.tsx b/src/CoordinateInfo/CoordinateInfo.tsx index abef2c1f05..2f859010c4 100644 --- a/src/CoordinateInfo/CoordinateInfo.tsx +++ b/src/CoordinateInfo/CoordinateInfo.tsx @@ -1,8 +1,9 @@ import Logger from '@terrestris/base-util/dist/Logger'; -import { isWmsLayer, WmsLayer } from '@terrestris/react-util/dist/Util/typeUtils'; +import {isWmsLayer, WmsLayer} from '@terrestris/react-util/dist/Util/typeUtils'; +import _cloneDeep from 'lodash/cloneDeep'; import _isString from 'lodash/isString'; -import { getUid } from 'ol'; -import { Coordinate as OlCoordinate } from 'ol/coordinate'; +import {getUid} from 'ol'; +import {Coordinate as OlCoordinate} from 'ol/coordinate'; import OlFeature from 'ol/Feature'; import OlFormatGML2 from 'ol/format/GML2'; import OlGeometry from 'ol/geom/Geometry'; @@ -11,8 +12,6 @@ import OlMap from 'ol/Map'; import OlMapBrowserEvent from 'ol/MapBrowserEvent'; import * as React from 'react'; -import _cloneDeep from 'lodash/cloneDeep'; - const format = new OlFormatGML2(); export interface CoordinateInfoProps { @@ -194,7 +193,7 @@ export class CoordinateInfo extends React.Component { - const features = {}; + const features: {[index: string]: OlFeature[]} = {}; textResponses.forEach((featureCollection: string, idx: number) => { const fc = format.readFeatures(featureCollection); diff --git a/src/Field/NominatimSearch/NominatimSearch.spec.tsx b/src/Field/NominatimSearch/NominatimSearch.spec.tsx index e3871b0a0c..3e6f195d52 100644 --- a/src/Field/NominatimSearch/NominatimSearch.spec.tsx +++ b/src/Field/NominatimSearch/NominatimSearch.spec.tsx @@ -56,14 +56,14 @@ describe('', () => { }); it('can be rendered', () => { - renderInMapContext(map, ); + renderInMapContext(map, ); const button = screen.getByRole('combobox'); expect(button).toBeVisible(); }); it('performs a search and shows options', async () => { - renderInMapContext(map, ); + renderInMapContext(map, ); const input = screen.getByRole('combobox'); @@ -88,7 +88,7 @@ describe('', () => { }); it('sets the text value of the search to the select item and zooms to the bounding box', async () => { - renderInMapContext(map, ); + renderInMapContext(map, ); const fitSpy = jest.spyOn(map.getView(), 'fit'); @@ -112,7 +112,7 @@ describe('', () => { it('calls a custom select callback', async () => { const selectSpy = jest.fn(); - renderInMapContext(map, ); + renderInMapContext(map, ); const fitSpy = jest.spyOn(map.getView(), 'fit'); diff --git a/src/Field/NominatimSearch/NominatimSearch.tsx b/src/Field/NominatimSearch/NominatimSearch.tsx index 0453c22d2e..ebe09b5629 100644 --- a/src/Field/NominatimSearch/NominatimSearch.tsx +++ b/src/Field/NominatimSearch/NominatimSearch.tsx @@ -2,10 +2,12 @@ import { AutoComplete } from 'antd'; import { AutoCompleteProps } from 'antd/lib/auto-complete'; import * as React from 'react'; const Option = AutoComplete.Option; -import { DefaultOptionType, OptionProps } from 'antd/lib/select'; +import './NominatimSearch.less'; import Logger from '@terrestris/base-util/dist/Logger'; import UrlUtil from '@terrestris/base-util/dist/UrlUtil/UrlUtil'; +import useMap from '@terrestris/react-util/dist/Hooks/useMap/useMap'; +import { DefaultOptionType, OptionProps } from 'antd/lib/select'; import { GeoJSON } from 'geojson'; import { Extent as OlExtent } from 'ol/extent'; import OlMap from 'ol/Map'; @@ -13,9 +15,6 @@ import { transformExtent } from 'ol/proj'; import { FC, useCallback, useEffect, useState } from 'react'; import { CSS_PREFIX } from '../../constants'; -import useMap from '../../Hook/useMap'; - -import './NominatimSearch.less'; // See https://nominatim.org/release-docs/develop/api/Output/ for some more information export type NominatimPlace = { @@ -272,7 +271,7 @@ export const NominatimSearch: FC = ({ * * @param option The selected OptionData */ - const onMenuItemSelected = useCallback((_, option: NominatimPlace) => { + const onMenuItemSelected = useCallback((_: any, option: NominatimPlace) => { if (!map) { return; } diff --git a/src/Field/ScaleCombo/ScaleCombo.spec.tsx b/src/Field/ScaleCombo/ScaleCombo.spec.tsx index f5ae6dfc6f..019831031f 100644 --- a/src/Field/ScaleCombo/ScaleCombo.spec.tsx +++ b/src/Field/ScaleCombo/ScaleCombo.spec.tsx @@ -36,7 +36,8 @@ describe('', () => { const wrapper = TestUtil.mountComponent(ScaleCombo, { map }); - expect(wrapper.instance().getOptionsFromMap).not.toBeUndefined(); + const instance = wrapper.instance() as ScaleCombo; + expect(instance.getOptionsFromMap).not.toBeUndefined(); }); it('creates options array from resolutions set on the map', () => { @@ -64,8 +65,8 @@ describe('', () => { // Reset the scales array, as getOptionsFromMap() will be called in // constructor. wrapper.setState({scales: []}); - - const scales = wrapper.instance().getOptionsFromMap(); + const instance = wrapper.instance() as ScaleCombo; + const scales = instance.getOptionsFromMap(); expect(scales).toBeInstanceOf(Array); TestUtil.removeMap(map); @@ -85,12 +86,14 @@ describe('', () => { // constructor. wrapper.setState({scales: []}); - const scales = wrapper.instance().getOptionsFromMap(); + const instance = wrapper.instance() as ScaleCombo; + const scales = instance.getOptionsFromMap(); + expect(scales).toBeInstanceOf(Array); expect(scales).toHaveLength(testResolutions.length); - const roundScale = (Math.round(MapUtil.getScaleForResolution( - testResolutions[testResolutions.length - 1] ,'m'))); + let testResolution = testResolutions[testResolutions.length - 1]; + const roundScale = (Math.round(MapUtil.getScaleForResolution(testResolution ,'m')!)); expect(scales[0]).toBe(roundScale); @@ -104,7 +107,7 @@ describe('', () => { }); // eslint-disable-next-line - const resolutionsFilter = res => { + const resolutionsFilter = (res: number) => { return res >= 19 || res <= 13; }; @@ -120,12 +123,13 @@ describe('', () => { // constructor. wrapper.setState({scales: []}); - const scales = wrapper.instance().getOptionsFromMap(); + const instance = wrapper.instance() as ScaleCombo; + const scales = instance.getOptionsFromMap(); expect(scales).toBeInstanceOf(Array); expect(scales).toHaveLength(expectedLength); const roundScale = MapUtil.roundScale(MapUtil.getScaleForResolution( - testResolutions[testResolutions.length - 2] ,'m')); + testResolutions[testResolutions.length - 2] ,'m')!); expect(scales[1]).toBe(roundScale); @@ -139,7 +143,8 @@ describe('', () => { const wrapper = TestUtil.mountComponent(ScaleCombo, { map }); - expect(wrapper.instance().determineOptionKeyForZoomLevel).not.toBeUndefined(); + const instance = wrapper.instance() as ScaleCombo; + expect(instance.determineOptionKeyForZoomLevel).not.toBeUndefined(); }); it('returns "undefied" for erronous zoom level or if exceeds number of valid zoom levels ', () => { @@ -150,11 +155,10 @@ describe('', () => { scales: scaleArray }); - expect(wrapper.instance().determineOptionKeyForZoomLevel(undefined)).toBeUndefined(); - expect(wrapper.instance().determineOptionKeyForZoomLevel(null)).toBeUndefined(); - expect(wrapper.instance().determineOptionKeyForZoomLevel('foo')).toBeUndefined(); - expect(wrapper.instance().determineOptionKeyForZoomLevel(17.123)).toBeUndefined(); - expect(wrapper.instance().determineOptionKeyForZoomLevel(scaleArray.length)).toBeUndefined(); + let component = wrapper.instance() as ScaleCombo; + expect(component.determineOptionKeyForZoomLevel(undefined)).toBeUndefined(); + expect(component.determineOptionKeyForZoomLevel(17.123)).toBeUndefined(); + expect(component.determineOptionKeyForZoomLevel(scaleArray.length)).toBeUndefined(); TestUtil.removeMap(map); }); @@ -167,7 +171,8 @@ describe('', () => { scales: scaleArray }); const index = 1; - expect(wrapper.instance().determineOptionKeyForZoomLevel(index)).toBe(scaleArray[index].toString()); + let component = wrapper.instance() as ScaleCombo; + expect(component.determineOptionKeyForZoomLevel(index)).toBe(scaleArray[index].toString()); TestUtil.removeMap(map); }); diff --git a/src/Field/ScaleCombo/ScaleCombo.tsx b/src/Field/ScaleCombo/ScaleCombo.tsx index 264687b763..98815128ab 100644 --- a/src/Field/ScaleCombo/ScaleCombo.tsx +++ b/src/Field/ScaleCombo/ScaleCombo.tsx @@ -261,7 +261,10 @@ class ScaleCombo extends React.Component { * * @return Option element for provided zoom level */ - determineOptionKeyForZoomLevel = (zoom: number): string | undefined => { + determineOptionKeyForZoomLevel = (zoom?: number): string | undefined => { + if (_isNil(zoom)) { + return undefined; + } if (!_isInteger(zoom) || (this.state.scales.length - 1 - zoom) < 0) { return undefined; } diff --git a/src/Field/WfsSearch/WfsSearch.spec.tsx b/src/Field/WfsSearch/WfsSearch.spec.tsx index fd10841896..67b80126f5 100644 --- a/src/Field/WfsSearch/WfsSearch.spec.tsx +++ b/src/Field/WfsSearch/WfsSearch.spec.tsx @@ -1,5 +1,5 @@ -/* eslint-disable testing-library/render-result-naming-convention */ import Logger from '@terrestris/base-util/dist/Logger'; +import {OptionProps} from 'antd/lib/select'; import OlLayerTile from 'ol/layer/Tile'; import OlMap from 'ol/Map'; import OlSourceOsm from 'ol/source/OSM'; @@ -9,7 +9,7 @@ import { } from 'react-dom/test-utils'; import TestUtil from '../../Util/TestUtil'; -import WfsSearch from './WfsSearch'; +import WfsSearch, {WfsSearchProps, WfsSearchState} from './WfsSearch'; describe('', () => { it('is defined', () => { @@ -22,19 +22,17 @@ describe('', () => { }); describe('#onUpdateInput', () => { - it('resets state.data', () => { - const wrapper = TestUtil.mountComponent(WfsSearch); - wrapper.instance().onUpdateInput(); - expect(wrapper.state().data).toEqual([]); - }); it('sets the inputValue as state.searchTerm', () => { const wrapper = TestUtil.mountComponent(WfsSearch); + const instance = wrapper.instance() as WfsSearch; + const inputValue = 'a'; act(() => { - wrapper.instance().onUpdateInput(inputValue); + instance.onUpdateInput(inputValue); }); - expect(wrapper.state().searchTerm).toBe(inputValue); + let state = wrapper.state() as WfsSearchState; + expect(state.searchTerm).toBe(inputValue); }); it('sends a request if input is as long as props.minChars', () => { @@ -53,10 +51,11 @@ describe('', () => { } } }); - const doSearchSpy = jest.spyOn(wrapper.instance(), 'doSearch'); + const instance = wrapper.instance() as WfsSearch; + const doSearchSpy = jest.spyOn(instance, 'doSearch'); const inputValue = 'Deutsch'; act(() => { - wrapper.instance().onUpdateInput(inputValue); + instance.onUpdateInput(inputValue); }); expect(doSearchSpy).toHaveBeenCalled(); doSearchSpy.mockRestore(); @@ -74,12 +73,13 @@ describe('', () => { } }] }; - wrapper.instance().onFetchSuccess(response); + const instance = wrapper.instance() as WfsSearch; + instance.onFetchSuccess(response); const promise = new Promise(resolve => { setTimeout(resolve, 350); }); return promise.then(() => { - expect(wrapper.state().data).toEqual(response.features); + expect((wrapper.state() as WfsSearchState).data).toEqual(response.features); }); }); }); @@ -88,7 +88,8 @@ describe('', () => { it('sets the response as state.data', () => { const wrapper = TestUtil.mountComponent(WfsSearch); const loggerSpy = jest.spyOn(Logger, 'error'); - wrapper.instance().onFetchError('Peter'); + const instance = wrapper.instance() as WfsSearch; + instance.onFetchError('Peter'); expect(loggerSpy).toHaveBeenCalled(); expect(loggerSpy).toHaveBeenCalledWith('Error while requesting WFS GetFeature: Peter'); loggerSpy.mockRestore(); @@ -105,7 +106,7 @@ describe('', () => { } }]; const map = new OlMap({ - layers: [new OlLayerTile({ name: 'OSM', source: new OlSourceOsm() })], + layers: [new OlLayerTile({ source: new OlSourceOsm(), properties: {name: 'OSM'} })], view: new OlView({ projection: 'EPSG:4326', center: [37.40570, 8.81566], @@ -119,13 +120,15 @@ describe('', () => { onSelect: selectSpy, map }); + const instance = wrapper.instance() as WfsSearch; act(() => { wrapper.setState({ data: data }); }); act(() => { - wrapper.instance().onMenuItemSelected('Deutschland', { key: '752526' }); + const op: OptionProps = { key: '752526', children: null }; + instance.onMenuItemSelected('Deutschland', op); }); expect(selectSpy).toHaveBeenCalled(); expect(selectSpy).toHaveBeenCalledWith(data[0], map); @@ -149,7 +152,7 @@ describe('', () => { } }; const map = new OlMap({ - layers: [new OlLayerTile({ name: 'OSM', source: new OlSourceOsm() })], + layers: [new OlLayerTile({ source: new OlSourceOsm(), properties: {name: 'OSM'} })], view: new OlView({ projection: 'EPSG:4326', center: [37.40570, 8.81566], @@ -161,7 +164,7 @@ describe('', () => { const wrapper = TestUtil.mountComponent(WfsSearch, { map }); const fitSpy = jest.spyOn(map.getView(), 'fit'); - wrapper.props().onSelect(feature, map); + (wrapper.props() as WfsSearchProps).onSelect(feature, map); expect.assertions(3); @@ -187,7 +190,7 @@ describe('', () => { name: 'Deutschland' } }; - const option = wrapper.props().renderOption(feature, { + const option = (wrapper.props() as WfsSearchProps).renderOption(feature, { // Props must be passed to the renderOption function. displayValue: 'name', idProperty: 'id' @@ -207,7 +210,7 @@ describe('', () => { name: 'Deutschland' } }; - const option = wrapper.props().renderOption(feature, { + const option = (wrapper.props() as WfsSearchProps).renderOption(feature, { displayValue: 'name', idProperty: 'customId' }); diff --git a/src/Field/WfsSearch/WfsSearch.tsx b/src/Field/WfsSearch/WfsSearch.tsx index d0c1c5fc3d..90b39e1c26 100644 --- a/src/Field/WfsSearch/WfsSearch.tsx +++ b/src/Field/WfsSearch/WfsSearch.tsx @@ -12,6 +12,7 @@ import WfsFilterUtil, { AttributeDetails } from '@terrestris/ol-util/dist/WfsFil import { OptionProps } from 'antd/lib/select'; import _debounce from 'lodash/debounce'; import _isFunction from 'lodash/isFunction'; +import OlFeature from 'ol/Feature'; import OlFormatGeoJSON from 'ol/format/GeoJSON'; import OlSimpleGeometry from 'ol/geom/SimpleGeometry'; import OlMap from 'ol/Map'; @@ -81,7 +82,7 @@ interface OwnProps { * The default will display the property `name` if existing or the * property defined in `props.idProperty` (default is to `id`). */ - renderOption: (feature: any, props: WfsSearchProps) => React.ReactElement; + renderOption: (feature: any, props: Partial) => React.ReactElement; /** * An onSelect function which gets called with the selected feature as it is * returned by server. @@ -149,7 +150,7 @@ interface OwnProps { wfsFormatOptions?: any; } -interface WfsSearchState { +export interface WfsSearchState { searchTerm: string; data: Array; fetching: boolean; @@ -217,12 +218,14 @@ export class WfsSearch extends React.Component { const olView = olMap.getView(); const geoJsonFormat = new OlFormatGeoJSON(); const olFeature = geoJsonFormat.readFeature(feature); - const geometry = olFeature.getGeometry() as OlSimpleGeometry; + if (olFeature instanceof OlFeature) { + const geometry = olFeature.getGeometry() as OlSimpleGeometry; - if (geometry) { - olView.fit(geometry, { - duration: 500 - }); + if (geometry) { + olView.fit(geometry, { + duration: 500 + }); + } } } } diff --git a/src/Field/WfsSearchInput/WfsSearchInput.spec.tsx b/src/Field/WfsSearchInput/WfsSearchInput.spec.tsx index 0315c13a6d..b385c0ddf0 100644 --- a/src/Field/WfsSearchInput/WfsSearchInput.spec.tsx +++ b/src/Field/WfsSearchInput/WfsSearchInput.spec.tsx @@ -4,7 +4,7 @@ import { } from 'react-dom/test-utils'; import TestUtil from '../../Util/TestUtil'; -import WfsSearchInput from './WfsSearchInput'; +import WfsSearchInput, {WfsSearchInputProps, WfsSearchState} from './WfsSearchInput'; describe('', () => { it('is defined', () => { @@ -19,8 +19,9 @@ describe('', () => { describe('#onUpdateInput', () => { it('resets state.data', () => { const wrapper = TestUtil.mountComponent(WfsSearchInput); - wrapper.instance().onUpdateInput(); - expect(wrapper.state().data).toEqual([]); + const instance = wrapper.instance() as WfsSearchInput; + instance.onUpdateInput(); + expect((wrapper.state() as WfsSearchState).data).toEqual([]); }); it('sets the inputValue as state.searchTerm', () => { @@ -31,9 +32,10 @@ describe('', () => { } }; act(() => { - wrapper.instance().onUpdateInput(evt); + const instance = wrapper.instance() as WfsSearchInput; + instance.onUpdateInput(evt); }); - expect(wrapper.state().searchTerm).toBe(evt.target.value); + expect((wrapper.state() as WfsSearchState).searchTerm).toBe(evt.target.value); }); it('calls onBeforeSearch callback if passed in props', () => { @@ -49,9 +51,10 @@ describe('', () => { }; act(() => { - wrapper.instance().onUpdateInput(evt); + const instance = wrapper.instance() as WfsSearchInput; + instance.onUpdateInput(evt); }); - expect(wrapper.props().onBeforeSearch).toHaveBeenCalled(); + expect((wrapper.props() as WfsSearchInputProps).onBeforeSearch).toHaveBeenCalled(); }); it('sends a request if input is as long as props.minChars', () => { @@ -70,14 +73,16 @@ describe('', () => { } } }); - const doSearchSpy = jest.spyOn(wrapper.instance(), 'doSearch'); + + const instance = wrapper.instance() as WfsSearchInput; + const doSearchSpy = jest.spyOn(instance, 'doSearch'); const evt = { target: { value: 'abc' } }; act(() => { - wrapper.instance().onUpdateInput(evt); + instance.onUpdateInput(evt); }); expect(doSearchSpy).toHaveBeenCalled(); doSearchSpy.mockRestore(); @@ -95,12 +100,13 @@ describe('', () => { } }] }; - wrapper.instance().onFetchSuccess(response); + const instance = wrapper.instance() as WfsSearchInput; + instance.onFetchSuccess(response); const promise = new Promise(resolve => { setTimeout(resolve, 350); }); return promise.then(() => { - expect(wrapper.state().data).toEqual(response.features); + expect((wrapper.state() as WfsSearchState).data).toEqual(response.features); }); }); }); @@ -109,7 +115,8 @@ describe('', () => { it('sets the response as state.data', () => { const wrapper = TestUtil.mountComponent(WfsSearchInput); const loggerSpy = jest.spyOn(Logger, 'error'); - wrapper.instance().onFetchError('Peter'); + const instance = wrapper.instance() as WfsSearchInput; + instance.onFetchError('Peter'); expect(loggerSpy).toHaveBeenCalled(); expect(loggerSpy).toHaveBeenCalledWith('Error while requesting WFS GetFeature: Peter'); loggerSpy.mockRestore(); @@ -119,9 +126,10 @@ describe('', () => { describe('#resetSearch', () => { it('resets input value', () => { const wrapper = TestUtil.mountComponent(WfsSearchInput); - wrapper.instance()._inputRef.input.value = 'some value'; - wrapper.instance().resetSearch(); - expect(wrapper.instance()._inputRef.input.value).toBe(''); + const instance = wrapper.instance() as WfsSearchInput; + instance._inputRef.input.value = 'some value'; + instance.resetSearch(); + expect(instance._inputRef.input.value).toBe(''); }); it('resets state value for data', () => { @@ -135,12 +143,13 @@ describe('', () => { }] }); }); - expect(wrapper.state().data.length).toBe(1); + expect((wrapper.state() as WfsSearchState).data.length).toBe(1); act(() => { - wrapper.instance().resetSearch(); + const instance = wrapper.instance() as WfsSearchInput; + instance.resetSearch(); }); - expect(wrapper.state().data.length).toBe(0); - expect(wrapper.state().data).toEqual([]); + expect((wrapper.state() as WfsSearchState).data.length).toBe(0); + expect((wrapper.state() as WfsSearchState).data).toEqual([]); }); @@ -150,9 +159,10 @@ describe('', () => { onClearClick: jest.fn() }); act(() => { - wrapper.instance().resetSearch(); + const instance = wrapper.instance() as WfsSearchInput; + instance.resetSearch(); }); - expect(wrapper.props().onClearClick).toHaveBeenCalled(); + expect((wrapper.props() as WfsSearchInputProps).onClearClick).toHaveBeenCalled(); }); }); }); diff --git a/src/Field/WfsSearchInput/WfsSearchInput.tsx b/src/Field/WfsSearchInput/WfsSearchInput.tsx index 770146a1e8..ee84dd6e17 100644 --- a/src/Field/WfsSearchInput/WfsSearchInput.tsx +++ b/src/Field/WfsSearchInput/WfsSearchInput.tsx @@ -147,7 +147,7 @@ interface OwnProps { wfsFormatOptions?: any; } -interface WfsSearchState { +export interface WfsSearchState { searchTerm: string; data: Feature[]; fetching: boolean; @@ -232,7 +232,7 @@ export class WfsSearchInput extends React.Component', () => { - let map; - let features; + let map: OlMap; + let features: OlFeature[]; beforeEach(() => { map = TestUtil.createMap(); @@ -44,26 +49,29 @@ describe('', () => { expect(layerCand).toHaveLength(1); expect(layerCand[0]).toBeInstanceOf(OlLayerVector); - expect(wrapper.instance()._source).toBeInstanceOf(OlSourceVector); - expect(wrapper.instance()._layer).toBeInstanceOf(OlLayerVector); + const instance1 = wrapper.instance() as AgFeatureGrid; + expect(instance1._source).toBeInstanceOf(OlSourceVector); + expect(instance1._layer).toBeInstanceOf(OlLayerVector); }); it('initializes a vector layer if it\'s not already added to the map only', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map}); + const instance = wrapper.instance() as AgFeatureGrid; - wrapper.instance().initVectorLayer(map); + instance.initVectorLayer(map); const layerCand = map.getLayers().getArray().filter(layer => layer.get('name') === wrapper.prop('layerName')); expect(layerCand).toHaveLength(1); expect(layerCand[0]).toBeInstanceOf(OlLayerVector); - expect(wrapper.instance()._source).toBeInstanceOf(OlSourceVector); - expect(wrapper.instance()._layer).toBeInstanceOf(OlLayerVector); + expect(instance._source).toBeInstanceOf(OlSourceVector); + expect(instance._layer).toBeInstanceOf(OlLayerVector); }); it('sets the given featureStyle to the featurelayer', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - expect(wrapper.instance()._layer.getStyle()).toEqual(wrapper.prop('featureStyle')); + const instance = wrapper.instance() as AgFeatureGrid; + expect(instance._layer?.getStyle()).toEqual(wrapper.prop('featureStyle')); }); it('removes the vector layer from the map on unmount', () => { @@ -82,9 +90,10 @@ describe('', () => { const mapOnSpy = jest.spyOn(map, 'on'); const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, selectable: true}); + const instance = wrapper.instance() as AgFeatureGrid; - const onPointerMove = wrapper.instance().onMapPointerMove; - const onMapSingleClick = wrapper.instance().onMapSingleClick; + const onPointerMove = instance.onMapPointerMove; + const onMapSingleClick = instance.onMapSingleClick; expect(mapOnSpy).toHaveBeenCalledTimes(2); expect(mapOnSpy).toHaveBeenCalledWith('pointermove', onPointerMove); @@ -95,10 +104,11 @@ describe('', () => { it('unregisters a pointermove and singleclick map event handler on unmount', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, selectable: true}); + const instance = wrapper.instance() as AgFeatureGrid; const mapUnSpy = jest.spyOn(map, 'un'); - const onPointerMove = wrapper.instance().onMapPointerMove; - const onMapSingleClick = wrapper.instance().onMapSingleClick; + const onPointerMove = instance.onMapPointerMove; + const onMapSingleClick = instance.onMapSingleClick; wrapper.unmount(); @@ -111,8 +121,8 @@ describe('', () => { it('generates the column definition out of the given features and takes attributeBlacklist into account', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - - const got = wrapper.instance().getColumnDefs(); + const instance = wrapper.instance() as AgFeatureGrid; + const got = instance.getColumnDefs(); const exp = [{ field: 'id', @@ -128,7 +138,7 @@ describe('', () => { attributeBlacklist: ['id'] }); - const gotBlacklisted = wrapper.instance().getColumnDefs(); + const gotBlacklisted = instance.getColumnDefs(); const expBlacklisted = [{ field: 'name', @@ -140,8 +150,8 @@ describe('', () => { it('generates the appropriate data to render', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - - const got = wrapper.instance().getRowData(); + const instance = wrapper.instance() as AgFeatureGrid; + const got = instance.getRowData(); const expRows = [{ id: 1, @@ -155,21 +165,25 @@ describe('', () => { }]; expRows.forEach((row, idx) => { - expect(row.id).toEqual(got[idx].id); - expect(row.name).toEqual(got[idx].name); + let gotElement = got[idx] as any; + expect(row.id).toEqual(gotElement.id); + expect(row.name).toEqual(gotElement.name); }); }); it('fits the map to show all given features', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); + const instance = wrapper.instance() as AgFeatureGrid; const mapViewFitSpy = jest.spyOn(map.getView(), 'fit'); - wrapper.instance().zoomToFeatures(features); + instance.zoomToFeatures(features); - const featGeometries = []; + const featGeometries: OlGeometry[] = []; features.forEach(feature => { - featGeometries.push(feature.getGeometry()); + if (!_isNil(feature.getGeometry())) { + featGeometries.push(feature.getGeometry()!); + } }); expect(mapViewFitSpy).toHaveBeenCalledWith(new OlGeomGeometryCollection(featGeometries).getExtent()); @@ -177,8 +191,8 @@ describe('', () => { it('highlights all given features', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - - wrapper.instance().highlightFeatures(features); + const instance = wrapper.instance() as AgFeatureGrid; + instance.highlightFeatures(features); features.forEach(feature => { expect(feature.getStyle()).toEqual(wrapper.prop('highlightStyle')); @@ -187,8 +201,8 @@ describe('', () => { it('selects all given features', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - - wrapper.instance().selectFeatures(features); + const instance = wrapper.instance() as AgFeatureGrid; + instance.selectFeatures(features); features.forEach(feature => { expect(feature.getStyle()).toEqual(wrapper.prop('selectStyle')); @@ -197,8 +211,8 @@ describe('', () => { it('resets all given features to default feature style', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); - - wrapper.instance().resetFeatureStyles(features); + const instance = wrapper.instance() as AgFeatureGrid; + instance.resetFeatureStyles(); features.forEach(feature => { expect(feature.getStyle()).toBe(undefined); @@ -207,22 +221,26 @@ describe('', () => { it('returns the feature for a given row key', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features}); + const instance = wrapper.instance() as AgFeatureGrid; + // @ts-ignore const rowKey = features[1].ol_uid; - expect(wrapper.instance().getFeatureFromRowKey(rowKey)).toEqual(features[1]); + expect(instance.getFeatureFromRowKey(rowKey)).toEqual(features[1]); }); it('selects the feature on row click', () => { const onRowClickSpy = jest.fn(); const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features, onRowClick: onRowClickSpy}); + const instance = wrapper.instance() as AgFeatureGrid; const clickedRow = { data: { + // @ts-ignore key: features[0].ol_uid } - }; - const zoomToFeaturesSpy = jest.spyOn(wrapper.instance(), 'zoomToFeatures'); + } as RowClickedEvent; + const zoomToFeaturesSpy = jest.spyOn(instance, 'zoomToFeatures'); - wrapper.instance().onRowClick(clickedRow); + instance.onRowClick(clickedRow); expect(onRowClickSpy).toHaveBeenCalled(); expect(zoomToFeaturesSpy).not.toHaveBeenCalled(); @@ -236,12 +254,14 @@ describe('', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map, features, onRowMouseOver: onRowMouseOverSpy}); const clickedRow = { data: { + // @ts-ignore key: features[0].ol_uid } - }; - const highlightFeaturesSpy = jest.spyOn(wrapper.instance(), 'highlightFeatures'); + } as CellMouseOverEvent; + const instance = wrapper.instance() as AgFeatureGrid; + const highlightFeaturesSpy = jest.spyOn(instance, 'highlightFeatures'); - wrapper.instance().onRowMouseOver(clickedRow); + instance.onRowMouseOver(clickedRow); expect(onRowMouseOverSpy).toHaveBeenCalled(); expect(highlightFeaturesSpy).toHaveBeenCalled(); @@ -252,13 +272,13 @@ describe('', () => { it('handles the change of props', () => { const wrapper = TestUtil.mountComponent(AgFeatureGrid, {map: map}); + const instance = wrapper.instance() as AgFeatureGrid; + expect(instance._source).toBeInstanceOf(OlSourceVector); + expect(instance._layer).toBeInstanceOf(OlLayerVector); - expect(wrapper.instance()._source).toBeInstanceOf(OlSourceVector); - expect(wrapper.instance()._layer).toBeInstanceOf(OlLayerVector); - - expect(wrapper.instance()._source.getFeatures()).toEqual([]); + expect(instance._source?.getFeatures()).toEqual([]); - const zoomToFeaturesSpy = jest.spyOn(wrapper.instance(), 'zoomToFeatures'); + const zoomToFeaturesSpy = jest.spyOn(instance, 'zoomToFeatures'); wrapper.setProps({ map: map, @@ -266,7 +286,7 @@ describe('', () => { zoomToExtent: true }); - expect(wrapper.instance()._source.getFeatures()).toEqual(features); + expect(instance._source?.getFeatures()).toEqual(features); expect(zoomToFeaturesSpy).toHaveBeenCalled(); zoomToFeaturesSpy.mockRestore(); @@ -329,13 +349,14 @@ describe('', () => { wrapper.setState({ selectedRows: selectionCurrent }, () => { + const instance = wrapper.instance() as AgFeatureGrid; const mockedEvt = { api: { getSelectedRows: mockedGetSelectedRows - } + }, }; act(() => { - wrapper.instance().onSelectionChanged(mockedEvt); + instance.onSelectionChanged(mockedEvt as any as SelectionChangedEvent); }); expect(onRowSelectionChange).toHaveBeenCalledTimes(1); // selectedRows is the first passed parameter diff --git a/src/Grid/AgFeatureGrid/AgFeatureGrid.tsx b/src/Grid/AgFeatureGrid/AgFeatureGrid.tsx index e29c2e3d4c..293c7522f8 100644 --- a/src/Grid/AgFeatureGrid/AgFeatureGrid.tsx +++ b/src/Grid/AgFeatureGrid/AgFeatureGrid.tsx @@ -245,13 +245,13 @@ export class AgFeatureGrid extends React.Component | null = null; + _source: OlSourceVector | null = null; /** * The layer representing the features of the grid. * @private */ - _layer: OlLayerVector> | null = null; + _layer: OlLayerVector | null = null; /** * The constructor. @@ -605,7 +605,7 @@ export class AgFeatureGrid extends React.Component !(properties[key] instanceof OlGeometry)) - .reduce((obj, key) => { + .reduce((obj: {[k: string]: any}, key) => { obj[key] = properties[key]; return obj; }, {}); diff --git a/src/Grid/FeatureGrid/FeatureGrid.spec.tsx b/src/Grid/FeatureGrid/FeatureGrid.spec.tsx index 36670bb77d..92ede432cf 100644 --- a/src/Grid/FeatureGrid/FeatureGrid.spec.tsx +++ b/src/Grid/FeatureGrid/FeatureGrid.spec.tsx @@ -1,7 +1,9 @@ -import { MapBrowserEvent } from 'ol'; +import {MapBrowserEvent} from 'ol'; +import OlFeature from 'ol/Feature'; import OlGeometry from 'ol/geom/Geometry'; import OlGeomGeometryCollection from 'ol/geom/GeometryCollection'; import OlLayerVector from 'ol/layer/Vector'; +import OlMap from 'ol/Map'; import OlSourceVector from 'ol/source/Vector'; import { act @@ -11,8 +13,8 @@ import TestUtil from '../../Util/TestUtil'; import FeatureGrid from './FeatureGrid'; describe('', () => { - let map; - let features; + let map: OlMap; + let features: OlFeature[]; beforeEach(() => { map = TestUtil.createMap(); @@ -179,7 +181,7 @@ describe('', () => { const featGeometries: OlGeometry[] = []; features.forEach(feature => { if (feature.getGeometry()) { - featGeometries.push(feature.getGeometry()); + featGeometries.push(feature.getGeometry()!); } }); @@ -198,6 +200,7 @@ describe('', () => { it('unhighlight all given features, but takes selection into account', () => { const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features}); + // @ts-ignore const selectedFeatureUid = features[0].ol_uid; act(() => { @@ -208,6 +211,7 @@ describe('', () => { }); features.forEach(feature => { + // @ts-ignore if (feature.ol_uid === selectedFeatureUid) { expect(feature.getStyle()).toEqual(wrapper.prop('selectStyle')); } else { @@ -238,6 +242,7 @@ describe('', () => { it('sets the appropriate select style to a feature if selection in grid changes', () => { const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features}); + // @ts-ignore const selectedRowKeys = [features[0].ol_uid, features[1].ol_uid]; act(() => { @@ -245,6 +250,7 @@ describe('', () => { }); features.forEach(feature => { + // @ts-ignore if (selectedRowKeys.includes(feature.ol_uid)) { expect(feature.getStyle()).toEqual(wrapper.prop('selectStyle')); } else { @@ -257,6 +263,7 @@ describe('', () => { it('returns the feature for a given row key', () => { const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features}); + // @ts-ignore const rowKey = features[1].ol_uid; expect((wrapper.instance() as FeatureGrid).getFeatureFromRowKey(rowKey)).toEqual(features[1]); @@ -266,6 +273,7 @@ describe('', () => { const onRowClickSpy = jest.fn(); const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features, onRowClick: onRowClickSpy}); const clickedRow = { + // @ts-ignore key: features[0].ol_uid }; const zoomToFeaturesSpy = jest.spyOn((wrapper.instance() as FeatureGrid), 'zoomToFeatures'); @@ -283,6 +291,7 @@ describe('', () => { const onRowMouseOverSpy = jest.fn(); const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features, onRowMouseOver: onRowMouseOverSpy}); const clickedRow = { + // @ts-ignore key: features[0].ol_uid }; const highlightFeaturesSpy = jest.spyOn((wrapper.instance() as FeatureGrid), 'highlightFeatures'); @@ -300,6 +309,7 @@ describe('', () => { const onRowMouseOutSpy = jest.fn(); const wrapper = TestUtil.mountComponent(FeatureGrid, {map, features, onRowMouseOut: onRowMouseOutSpy}); const clickedRow = { + // @ts-ignore key: features[0].ol_uid }; const unhighlightFeaturesSpy = jest.spyOn((wrapper.instance() as FeatureGrid), 'unhighlightFeatures'); diff --git a/src/Grid/FeatureGrid/FeatureGrid.tsx b/src/Grid/FeatureGrid/FeatureGrid.tsx index ee025a3161..62528fe067 100644 --- a/src/Grid/FeatureGrid/FeatureGrid.tsx +++ b/src/Grid/FeatureGrid/FeatureGrid.tsx @@ -212,13 +212,13 @@ export class FeatureGrid extends React.Component | null = null; + _source: OlSourceVector | null = null; /** * The layer representing the features of the grid. * @private */ - _layer: OlLayerVector> | null = null; + _layer: OlLayerVector | null = null; /** * The constructor. @@ -524,6 +524,7 @@ export class FeatureGrid extends React.Component !(properties[key] instanceof OlGeometry)) - .reduce((obj, key) => { + .reduce((obj: {[k: string]: any}, key) => { obj[key] = properties[key]; return obj; }, {}); diff --git a/src/Grid/PropertyGrid/PropertyGrid.spec.tsx b/src/Grid/PropertyGrid/PropertyGrid.spec.tsx index ef72cd73ae..c2d676e963 100644 --- a/src/Grid/PropertyGrid/PropertyGrid.spec.tsx +++ b/src/Grid/PropertyGrid/PropertyGrid.spec.tsx @@ -1,3 +1,5 @@ +import _get from 'lodash/get'; +import _isNil from 'lodash/isNil'; import OlFeature from 'ol/Feature'; import OlGeomPoint from 'ol/geom/Point'; @@ -58,8 +60,9 @@ describe('', () => { expect(dataSource).toHaveLength(Object.keys(attributeObject).length); dataSource.forEach((dataSourceElement) => { const attributeName = dataSourceElement.attributeName; + // @ts-ignore const key = `ATTR_${attributeName}_fid_${testFeature.ol_uid}`; - expect(attributeObject[attributeName]).toBe(dataSourceElement.attributeValue); + expect(_get(attributeObject,attributeName)).toBe(dataSourceElement.attributeValue); expect(key).toBe(dataSourceElement.key); }); @@ -125,9 +128,9 @@ describe('', () => { dataSource.forEach((dataSourceElement) => { const key = dataSourceElement.key; const orignalAttributeName = key.split('_')[1]; - if (attributeNames[orignalAttributeName]) { + if (!_isNil(_get(attributeNames, orignalAttributeName))) { const mappedAttributeNameInDataSource = dataSourceElement.attributeName; - expect(mappedAttributeNameInDataSource).toBe(attributeNames[orignalAttributeName]); + expect(mappedAttributeNameInDataSource).toEqual(_get(attributeNames, orignalAttributeName)); } }); }); diff --git a/src/LayerSwitcher/LayerSwitcher.spec.tsx b/src/LayerSwitcher/LayerSwitcher.spec.tsx index ed05f0e7ff..68fcabb89d 100644 --- a/src/LayerSwitcher/LayerSwitcher.spec.tsx +++ b/src/LayerSwitcher/LayerSwitcher.spec.tsx @@ -1,6 +1,8 @@ import { render, screen,within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import OlLayer from 'ol/layer/Layer'; import OlLayerTile from 'ol/layer/Tile'; +import OlMap from 'ol/Map'; import OlSourceOsm from 'ol/source/OSM'; import React from 'react'; @@ -8,8 +10,8 @@ import TestUtil from '../Util/TestUtil'; import LayerSwitcher from './LayerSwitcher'; describe('', () => { - let map; - let layers; + let map: OlMap; + let layers: OlLayer[]; beforeEach(() => { layers = [ @@ -26,9 +28,8 @@ describe('', () => { }); afterEach(() => { - map.dispose(); - layers = null; - map = null; + map?.dispose(); + layers = []; }); it('is defined', () => { @@ -78,13 +79,13 @@ describe('', () => { const { container } = render(); const switcher = within(container).getByRole('button'); - const layer0visibile = layers[0].getVisible(); - const layer1visibile = layers[1].getVisible(); + const layer0visible = layers[0].getVisible(); + const layer1visible = layers[1].getVisible(); await userEvent.click(switcher); - expect(layers[0].getVisible()).toBe(!layer0visibile); - expect(layers[1].getVisible()).toBe(!layer1visibile); + expect(layers[0].getVisible()).toBe(!layer0visible); + expect(layers[1].getVisible()).toBe(!layer1visible); }); it('assumes the first provided layer as visible if the initial visibility of all layers is false', () => { diff --git a/src/LayerTree/LayerTreeNode/LayerTreeNode.spec.tsx b/src/LayerTree/LayerTreeNode/LayerTreeNode.spec.tsx index ce8456ae59..f3c464ef56 100644 --- a/src/LayerTree/LayerTreeNode/LayerTreeNode.spec.tsx +++ b/src/LayerTree/LayerTreeNode/LayerTreeNode.spec.tsx @@ -8,7 +8,7 @@ describe('', () => { const defaultProps = { inResolutionRange: true, - filterTreeNode: ftn => ftn + filterTreeNode: jest.fn() }; it('is defined', () => { diff --git a/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.spec.tsx b/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.spec.tsx index b36fbc0cb6..b0603fd5e7 100644 --- a/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.spec.tsx +++ b/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.spec.tsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import moment from 'moment'; import OlLayerTile from 'ol/layer/Tile'; +import OlMap from 'ol/Map'; import OlSourceTileWMS from 'ol/source/TileWMS'; import * as React from 'react'; @@ -10,20 +11,22 @@ import TimeLayerSliderPanel from '../TimeLayerSliderPanel/TimeLayerSliderPanel'; describe('', () => { - let map; + let map: OlMap; const testLayerName = 'OSM-WMS'; const testLayerTitle = 'OSM-WMS - by terrestris'; const testLayer = new OlLayerTile({ visible: false, - title: testLayerTitle, source: new OlSourceTileWMS({ url: 'https://ows.terrestris.de/osm/service?', params: { LAYERS: testLayerName, TILED: true } - }) + }), + properties: { + title: testLayerTitle + } }); beforeEach(() => { diff --git a/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.tsx b/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.tsx index 37eb293446..08e28f9ce2 100644 --- a/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.tsx +++ b/src/Panel/TimeLayerSliderPanel/TimeLayerSliderPanel.tsx @@ -69,7 +69,7 @@ export class TimeLayerSliderPanel extends React.Component', () => { - let layer; + let layer: OlLayer; beforeEach(() => { - layer = TestUtil.createVectorLayer(); + layer = TestUtil.createVectorLayer({}); }); it('is defined', () => { @@ -27,7 +29,8 @@ describe('', () => { }; const wrapper = TestUtil.mountComponent(LayerTransparencySlider, props); - const transparency = wrapper.instance().getLayerTransparency(); + const instance = wrapper.instance() as LayerTransparencySlider; + const transparency = instance.getLayerTransparency(); expect(transparency).toBe(91); }); @@ -36,8 +39,9 @@ describe('', () => { layer: layer }; const wrapper = TestUtil.mountComponent(LayerTransparencySlider, props); + const instance = wrapper.instance() as LayerTransparencySlider; - wrapper.instance().setLayerTransparency(91); + instance.setLayerTransparency(91); expect(layer.getOpacity()).toBe(0.09); }); diff --git a/src/Slider/MultiLayerSlider/MultiLayerSlider.spec.tsx b/src/Slider/MultiLayerSlider/MultiLayerSlider.spec.tsx index 1839d347ce..e13d40d817 100644 --- a/src/Slider/MultiLayerSlider/MultiLayerSlider.spec.tsx +++ b/src/Slider/MultiLayerSlider/MultiLayerSlider.spec.tsx @@ -1,8 +1,10 @@ +import OlLayer from 'ol/layer/Layer'; + import TestUtil from '../../Util/TestUtil'; import MultiLayerSlider from './MultiLayerSlider'; describe('', () => { - let layers; + let layers: OlLayer[]; beforeEach(() => { layers = [ diff --git a/src/Slider/MultiLayerSlider/MultiLayerSlider.tsx b/src/Slider/MultiLayerSlider/MultiLayerSlider.tsx index 16dcde6aa5..7426a8fe10 100644 --- a/src/Slider/MultiLayerSlider/MultiLayerSlider.tsx +++ b/src/Slider/MultiLayerSlider/MultiLayerSlider.tsx @@ -151,7 +151,7 @@ class MultiLayerSlider extends React.Component { * @return The marks object */ getMarks() { - const marks = {}; + const marks: {[index: number]: any} = {}; const { layers, nameProperty diff --git a/src/Slider/TimeSlider/TimeSlider.spec.tsx b/src/Slider/TimeSlider/TimeSlider.spec.tsx index e04fdda4ab..1317447dac 100644 --- a/src/Slider/TimeSlider/TimeSlider.spec.tsx +++ b/src/Slider/TimeSlider/TimeSlider.spec.tsx @@ -14,7 +14,7 @@ describe('', () => { }); it('converts time millis properly', () => { - const slider = TestUtil.mountComponent(TimeSlider, {}).instance(); + const slider = TestUtil.mountComponent(TimeSlider, {}).instance() as TimeSlider; const time = moment(1500000000000); const unix = slider.convert(time); expect(unix).toBe(1500000000); @@ -35,7 +35,7 @@ describe('', () => { max: max.unix(), defaultValue: defaultValue.unix() }; - const slider = TestUtil.mountComponent(TimeSlider, props).instance(); + const slider = TestUtil.mountComponent(TimeSlider, props).instance() as TimeSlider; const got = slider.convertTimestamps(); expect(got).toEqual(expected); }); @@ -47,7 +47,7 @@ describe('', () => { const expected1 = val1.unix(); const expected2 = [expected1, val2.unix()]; - const slider = TestUtil.mountComponent(TimeSlider, {}).instance(); + const slider = TestUtil.mountComponent(TimeSlider, {}).instance() as TimeSlider; const got1 = slider.convert(val1); const got2 = slider.convert([val1, val2]); @@ -60,20 +60,20 @@ describe('', () => { const format = 'YYYY-MM-DD hh:mm:ss'; const val1 = moment('2000-01-01 12:00:00', format); const val2 = moment('2001-01-01 12:00:00', format); - const marks = {}; - marks[val1] = val1; - marks[val2] = val2; + const marks: any = {}; + marks['2000-01-01 12:00:00'] = val1; + marks['2001-01-01 12:00:00'] = val2; const expected1 = val1.unix(); const expected2 = val2.unix(); - const slider = TestUtil.mountComponent(TimeSlider, {}).instance(); + const slider = TestUtil.mountComponent(TimeSlider, {}).instance() as TimeSlider; const gotMarks = slider.convertMarks(marks); - const gotKeys = Object.keys(gotMarks); + const gotKeys = Object.keys(gotMarks!); expect(gotKeys).toEqual(expect.arrayContaining([expected1.toString(), expected2.toString()])); - expect(gotMarks[expected1]).toEqual(val1); - expect(gotMarks[expected2]).toEqual(val2); + expect(gotMarks![expected1]).toEqual(val1); + expect(gotMarks![expected2]).toEqual(val2); }); }); @@ -82,7 +82,7 @@ describe('', () => { const formatted = '2000-01-01 12:00:00'; const val = moment(formatted, format).unix(); - const slider = TestUtil.mountComponent(TimeSlider, {formatString: format}).instance(); + const slider = TestUtil.mountComponent(TimeSlider, {formatString: format}).instance() as TimeSlider; const got = slider.formatTimestamp(val); expect(got).toEqual(formatted); @@ -96,7 +96,7 @@ describe('', () => { const expected1 = moment(val1.unix() * 1000).toISOString(); const expected2 = [expected1, moment(val2.unix() * 1000).toISOString()]; - const slider = TestUtil.mountComponent(TimeSlider, {onChange}).instance(); + const slider = TestUtil.mountComponent(TimeSlider, {onChange}).instance() as TimeSlider; slider.valueUpdated(val1.unix()); expect(onChange.mock.calls.length).toBe(1); diff --git a/src/Slider/TimeSlider/TimeSlider.tsx b/src/Slider/TimeSlider/TimeSlider.tsx index 62bc0da7d8..c6cb688f2e 100644 --- a/src/Slider/TimeSlider/TimeSlider.tsx +++ b/src/Slider/TimeSlider/TimeSlider.tsx @@ -2,7 +2,7 @@ import { Slider } from 'antd'; import { SliderBaseProps,SliderMarks } from 'antd/lib/slider'; import _isArray from 'lodash/isArray'; import _isObject from 'lodash/isObject'; -import moment from 'moment'; +import moment, {Moment} from 'moment'; import * as React from 'react'; import { CSS_PREFIX } from '../../constants'; @@ -103,7 +103,7 @@ class TimeSlider extends React.Component { * @param val the input value(s) * @return The converted value(s) */ - convert(val: string[] | string): number | [number, number] { + convert(val: string[] | string | Moment | Moment[]): number | [number, number] { return _isArray(val) ? (val as Array).map(iso => moment(iso).unix()) as [number, number]: moment(val).unix() as number; diff --git a/src/Util/TestUtil.tsx b/src/Util/TestUtil.tsx index 7453a7813f..2b9b4b027a 100644 --- a/src/Util/TestUtil.tsx +++ b/src/Util/TestUtil.tsx @@ -8,7 +8,7 @@ import OlSourceVector from 'ol/source/Vector'; import OlView from 'ol/View'; import * as React from 'react'; -type Wrapper = ShallowWrapper | ReactWrapper; +export type Wrapper = ShallowWrapper | ReactWrapper; /** * A set of some useful static helper methods. @@ -140,7 +140,7 @@ export class TestUtil { clientY: position.top + y + TestUtil.mapDivHeight / 2, shiftKey }); - const olEvt = OlMapBrowserEvent(type, map, event, dragging); + const olEvt = new OlMapBrowserEvent(type, map, event, dragging); map.handleMapBrowserEvent(olEvt); }; @@ -162,7 +162,7 @@ export class TestUtil { /** * Returns a point feature with a random position. */ - static generatePointFeature = (props = { + static generatePointFeature = (props: {[k: string]: any} = { ATTR_1: Math.random() * 100, ATTR_2: 'Borsigplatz 9', ATTR_3: 'Dortmund' diff --git a/src/Util/antdTestQueries.ts b/src/Util/antdTestQueries.ts index 75c3eecbab..ccda92b394 100644 --- a/src/Util/antdTestQueries.ts +++ b/src/Util/antdTestQueries.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import {buildQueries, queryAllByTitle} from '@testing-library/react'; const allAntdDropdownOptionQuery = (container) => { diff --git a/src/custom.d.ts b/src/custom.d.ts index b9d7c54b17..62b95b45c7 100644 --- a/src/custom.d.ts +++ b/src/custom.d.ts @@ -1,7 +1,2 @@ declare module '*.png'; -declare module 'ol'; -declare module 'ol/format'; -declare module 'ol/layer'; -declare module 'ol/source'; -declare module 'ol/geom'; declare module '@camptocamp/inkmap'; diff --git a/tsconfig.json b/tsconfig.json index bdb8793e39..81b3209415 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,8 +18,8 @@ "rootDir": "src", "skipLibCheck": true, "sourceMap": true, - "suppressImplicitAnyIndexErrors": true, - "target": "es5" + "target": "es5", + "types": ["node", "jest", "@testing-library/jest-dom"] }, "exclude": [ "node_modules", @@ -34,7 +34,6 @@ "jest", "coverage", "src/Util/**", - "**.config.js", - "**/*.spec.tsx" + "src/**/*.spec.ts" ] }