Adding some first unit test and managing translations with scale=1
This commit is contained in:
1 parent
3a7d4987a3
commit
67e4d13989
4 files changed
+129
-7
No files matched your search
@@ -0,0 +1,69 @@
|
||||
import _ from 'lodash';
|
||||
import { initialMapState, reevaluateState } from './map';
|
||||
|
||||
//interface CustomMatchers<R = unknown> {
|
||||
// isDeepEqual(received: any, target: any): R;
|
||||
//}
|
||||
|
||||
//declare global {
|
||||
// namespace jest {
|
||||
// interface Expect extends CustomMatchers {}
|
||||
// interface Matchers<R> extends CustomMatchers<R> {}
|
||||
// interface InverseAsymmetricMatchers extends CustomMatchers {}
|
||||
// }
|
||||
//}
|
||||
|
||||
expect.extend({
|
||||
isDeepEqual: (received: any, target: any) => {
|
||||
const pass = _.isEqual(received, target);
|
||||
if (pass) {
|
||||
return { message: () => '', pass: true };
|
||||
}
|
||||
return {
|
||||
message: () =>
|
||||
`${JSON.stringify(received)} instead of\n ${JSON.stringify(target)}`,
|
||||
pass: false,
|
||||
};
|
||||
},
|
||||
isAlmostDeepEqual: (received: any, target: any, delta: number) => {
|
||||
const pass = _.isEqualWith(received, target, (r: any, t: any) => {
|
||||
if (typeof r !== 'number' || typeof t !== 'number') {
|
||||
return undefined;
|
||||
}
|
||||
console.log(`r: ${r}, t:${t}, ${Math.abs(r - t) <= delta}`);
|
||||
return Math.abs(r - t) <= delta;
|
||||
});
|
||||
if (pass) {
|
||||
return { message: () => '', pass: true };
|
||||
}
|
||||
return {
|
||||
message: () =>
|
||||
`${JSON.stringify(received)} instead of\n ${JSON.stringify(target)}`,
|
||||
pass: false,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
describe('Our isAlmostDeepEqual matcher', () => {
|
||||
test('compares correctly two numbers that are almost equals', () => {
|
||||
expect({ x: 1.001 }).isAlmostDeepEqual({ x: 1 }, 1e-2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Map store methods', () => {
|
||||
test('initialize its state', () => {
|
||||
const state = _.cloneDeep(initialMapState);
|
||||
expect(state.tiles.nb.x).not.toBe(0);
|
||||
});
|
||||
test('reevaluateState keeps the same values', () => {
|
||||
const state = _.cloneDeep(initialMapState);
|
||||
reevaluateState(state);
|
||||
expect(state).isAlmostDeepEqual(initialMapState, 1e-7);
|
||||
});
|
||||
test('reevaluateState computes the right longitude after a shift 50 pixels left', () => {
|
||||
const state = _.cloneDeep(initialMapState);
|
||||
state.slippy.translation.x = state.slippy.translation.x - 50;
|
||||
reevaluateState(state);
|
||||
expect(state.scope.center.lon).not.toBe(77.5539501);
|
||||
});
|
||||
});
|
||||
+45
-7
@@ -1,7 +1,14 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import _ from 'lodash';
|
||||
import { tileSize } from '../components/map/tiled-map';
|
||||
import { geoPoint, Point, lon2tile, lat2tile } from '../lib/geo';
|
||||
import {
|
||||
geoPoint,
|
||||
Point,
|
||||
lon2tile,
|
||||
lat2tile,
|
||||
tile2lat,
|
||||
tile2long,
|
||||
} from '../lib/geo';
|
||||
|
||||
// Top level properties (the other properties can be derived from them)
|
||||
|
||||
@@ -12,7 +19,7 @@ export interface MapScope {
|
||||
}
|
||||
const initialMapScope: MapScope = {
|
||||
center: { lat: -37.8403508, lon: 77.5539501 },
|
||||
zoom: 13.49,
|
||||
zoom: 13,
|
||||
};
|
||||
|
||||
// Derived properties
|
||||
@@ -60,7 +67,7 @@ const nbTilesY = _.ceil(mapState.viewport.height / tileSize) + 4;
|
||||
|
||||
*/
|
||||
|
||||
let initialMapState: MapState = {
|
||||
export var initialMapState: MapState = {
|
||||
scope: initialMapScope,
|
||||
slippy: {
|
||||
scale: 1,
|
||||
@@ -82,7 +89,8 @@ let initialMapState: MapState = {
|
||||
},
|
||||
};
|
||||
|
||||
const evaluateStateFromScope = (state: MapState) => {
|
||||
export const evaluateStateFromScope = (state: MapState) => {
|
||||
console.log('<<<<<<<<<<<< evaluateStateFromScope');
|
||||
state.tiles.zoom = _.round(state.scope.zoom);
|
||||
const softZoom = state.scope.zoom - state.tiles.zoom;
|
||||
state.slippy.scale = 2 ** softZoom;
|
||||
@@ -115,9 +123,37 @@ const evaluateStateFromScope = (state: MapState) => {
|
||||
|
||||
evaluateStateFromScope(initialMapState);
|
||||
|
||||
const reevaluateState = (state: MapState) => {};
|
||||
|
||||
|
||||
export const reevaluateState = (state: MapState) => {
|
||||
// Update the scope (center and zoom level)
|
||||
const centerPX = {
|
||||
x: window.innerWidth / 2,
|
||||
y: window.innerHeight / 2,
|
||||
};
|
||||
const visibleTileSize = tileSize / state.slippy.scale;
|
||||
const centerTiles = {
|
||||
x:
|
||||
state.tiles.first.x +
|
||||
(centerPX.x - state.slippy.translation.x) / visibleTileSize,
|
||||
y:
|
||||
state.tiles.first.y +
|
||||
(centerPX.y - state.slippy.translation.y) / visibleTileSize,
|
||||
};
|
||||
state.scope.center = {
|
||||
lat: tile2lat(centerTiles.y, state.tiles.zoom),
|
||||
lon: tile2long(centerTiles.x, state.tiles.zoom),
|
||||
};
|
||||
// TODO: zoom level
|
||||
if (
|
||||
-state.slippy.translation.x < visibleTileSize ||
|
||||
-state.slippy.translation.y < visibleTileSize ||
|
||||
-state.slippy.translation.x >
|
||||
(state.tiles.nb.x - 1) * visibleTileSize - window.innerWidth ||
|
||||
-state.slippy.translation.y >
|
||||
(state.tiles.nb.y - 1) * visibleTileSize - window.innerHeight
|
||||
) {
|
||||
evaluateStateFromScope(state);
|
||||
}
|
||||
};
|
||||
|
||||
const mapSlice = createSlice({
|
||||
name: 'map',
|
||||
@@ -131,6 +167,7 @@ const mapSlice = createSlice({
|
||||
x: state.slippy.translation.x + action.payload.x,
|
||||
y: state.slippy.translation.y + action.payload.y,
|
||||
};
|
||||
reevaluateState(state);
|
||||
},
|
||||
scale: (state, action) => {
|
||||
state.slippy.scale = state.slippy.scale * action.payload.factor;
|
||||
@@ -144,6 +181,7 @@ const mapSlice = createSlice({
|
||||
(state.slippy.translation.y - action.payload.center.y) *
|
||||
(action.payload.factor - 1),
|
||||
};
|
||||
reevaluateState(state);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user