forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmapChrome.test.ts
More file actions
119 lines (89 loc) · 4.02 KB
/
Copy pathmapChrome.test.ts
File metadata and controls
119 lines (89 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { describe, it, expect, beforeEach, vi } from 'vitest'
import {
MockMap,
NavigationControl,
GeolocateControl,
ScaleControl,
resetMapLibreMock,
} from '../test/mocks/maplibre-gl'
import type { Map as MapLibreMap } from 'maplibre-gl'
import { attachMapChrome } from './mapChrome'
// WIREFRAMES.md, map screen §5 and Interactions: compass is a
// `NavigationControl`, locate is a `GeolocateControl` with continuous tracking,
// scale is a `ScaleControl` in imperial by default. Compass and locate stack
// bottom-RIGHT (the thumb zone - everything tapped mid-walk sits in the lower
// third); the scale bar sits bottom-LEFT above the attribution.
//
// Zoom buttons are web-only. On a phone, pinch already covers zoom and the
// thumb zone is reserved for locate - shipping zoom buttons there would spend
// the most reachable part of the screen on the least necessary control.
vi.mock('maplibre-gl', () => import('../test/mocks/maplibre-gl'))
// The mock implements the slice of the map API this module actually uses
// (addControl / removeControl). The intersection keeps the recorded `controls`
// array visible to assertions while satisfying attachMapChrome's parameter,
// without loosening that function's real signature to accommodate a test.
function map() {
return new MockMap({}) as unknown as MockMap & MapLibreMap
}
function controlsOf(m: MockMap, kind: new (...args: never[]) => unknown) {
return m.controls.filter((c) => c.control instanceof kind)
}
beforeEach(() => {
resetMapLibreMock()
})
describe('attachMapChrome', () => {
it('puts compass and locate in the bottom-right thumb zone', () => {
const m = map()
attachMapChrome(m, { showZoomButtons: false, units: 'imperial' })
expect(controlsOf(m, NavigationControl)[0].position).toBe('bottom-right')
expect(controlsOf(m, GeolocateControl)[0].position).toBe('bottom-right')
})
it('puts the scale bar bottom-left, clear of the thumb zone', () => {
const m = map()
attachMapChrome(m, { showZoomButtons: false, units: 'imperial' })
expect(controlsOf(m, ScaleControl)[0].position).toBe('bottom-left')
})
it('tracks the user continuously rather than taking a single fix', () => {
const m = map()
attachMapChrome(m, { showZoomButtons: false, units: 'imperial' })
const locate = controlsOf(m, GeolocateControl)[0].control as GeolocateControl
expect(locate.options?.trackUserLocation).toBe(true)
})
it('shows zoom buttons on web, where there is no pinch gesture', () => {
const m = map()
attachMapChrome(m, { showZoomButtons: true, units: 'imperial' })
const nav = controlsOf(m, NavigationControl)[0].control as NavigationControl
expect(nav.options?.showZoom).toBe(true)
})
it('hides zoom buttons on touch, keeping the thumb zone for locate', () => {
const m = map()
attachMapChrome(m, { showZoomButtons: false, units: 'imperial' })
const nav = controlsOf(m, NavigationControl)[0].control as NavigationControl
expect(nav.options?.showZoom).toBe(false)
})
it('always keeps the compass, whatever the platform - tapping it resets north-up', () => {
for (const showZoomButtons of [true, false]) {
resetMapLibreMock()
const m = map()
attachMapChrome(m, { showZoomButtons, units: 'imperial' })
const nav = controlsOf(m, NavigationControl)[0].control as NavigationControl
expect(nav.options?.showCompass).toBe(true)
}
})
it.each([
['imperial', 'imperial'],
['metric', 'metric'],
] as const)('renders the scale bar in the %s unit preference', (units, expected) => {
const m = map()
attachMapChrome(m, { showZoomButtons: false, units })
const scale = controlsOf(m, ScaleControl)[0].control as ScaleControl
expect(scale.options?.unit).toBe(expected)
})
it('detaches every control it added, so a remount cannot stack duplicates', () => {
const m = map()
const detach = attachMapChrome(m, { showZoomButtons: true, units: 'imperial' })
expect(m.controls.length).toBeGreaterThan(0)
detach()
expect(m.controls).toHaveLength(0)
})
})