forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmapDetail.test.ts
More file actions
146 lines (124 loc) · 4.95 KB
/
Copy pathmapDetail.test.ts
File metadata and controls
146 lines (124 loc) · 4.95 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { describe, it, expect } from 'vitest'
import { DETAIL_HIDDEN_LAYERS, DETAIL_MANAGED_LAYERS, attachMapDetail } from './mapDetail'
import { LIVE_TOPO_LAYER_IDS } from './liveTopo'
import { MockMap } from '../test/mocks/maplibre-gl'
// MAP_STYLE_SPEC.md's detail matrix, asserted per level as the spec asks.
// These are cartographic decisions, not implementation details: which layers
// a level drops decides what a hiker stops seeing, so each level's exact set
// is pinned rather than derived.
describe('the detail matrix', () => {
it('hides nothing at full - the whole sheet, borders included', () => {
expect(DETAIL_HIDDEN_LAYERS.full).toEqual([])
})
it('hides exactly the admin borders at standard', () => {
// Wanted sometimes, distracting mostly - and standard is the default, so
// this line is what everyone on the defaults sees.
expect([...DETAIL_HIDDEN_LAYERS.standard].sort()).toEqual(
[LIVE_TOPO_LAYER_IDS.boundary].sort(),
)
})
it('hides the fine grain at minimal, and only the fine grain', () => {
expect([...DETAIL_HIDDEN_LAYERS.minimal].sort()).toEqual(
[
LIVE_TOPO_LAYER_IDS.boundary,
LIVE_TOPO_LAYER_IDS.track,
LIVE_TOPO_LAYER_IDS.roadMinor,
LIVE_TOPO_LAYER_IDS.contour,
LIVE_TOPO_LAYER_IDS.contourLabel,
LIVE_TOPO_LAYER_IDS.waterLabel,
LIVE_TOPO_LAYER_IDS.scrub,
].sort(),
)
})
it('keeps terrain and navigation out of reach of every level', () => {
// The spec's own floor: index contours so the land still has shape, paths
// because a side trail is hiker signal, and the layers a hiker orients by
// - peaks, places, water, major roads. A level that could hide one of
// these has stopped being a detail control.
for (const kept of [
LIVE_TOPO_LAYER_IDS.contourIndex,
LIVE_TOPO_LAYER_IDS.path,
LIVE_TOPO_LAYER_IDS.peak,
LIVE_TOPO_LAYER_IDS.place,
LIVE_TOPO_LAYER_IDS.roadMajor,
LIVE_TOPO_LAYER_IDS.roadMajorCasing,
LIVE_TOPO_LAYER_IDS.water,
LIVE_TOPO_LAYER_IDS.waterway,
LIVE_TOPO_LAYER_IDS.wood,
LIVE_TOPO_LAYER_IDS.hillshade,
]) {
expect(DETAIL_MANAGED_LAYERS, kept).not.toContain(kept)
}
})
it('nests the levels: everything standard hides, minimal hides too', () => {
for (const layer of DETAIL_HIDDEN_LAYERS.standard) {
expect(DETAIL_HIDDEN_LAYERS.minimal).toContain(layer)
}
})
})
describe('attachMapDetail', () => {
const liveSheet = () => {
const m = new MockMap({})
m.layerIds = [LIVE_TOPO_LAYER_IDS.wood, ...DETAIL_MANAGED_LAYERS]
return m
}
it('writes every managed layer, hidden or shown, so a level change restores', () => {
// `visibility` is sticky: a loop that only wrote `none` would make the
// detail control a one-way ratchet, minimal forever.
const m = liveSheet()
attachMapDetail(m as never, 'minimal')
for (const layer of DETAIL_MANAGED_LAYERS) {
expect(m.layoutProperties.get(`${layer}/visibility`)).toBe('none')
}
attachMapDetail(m as never, 'full')
for (const layer of DETAIL_MANAGED_LAYERS) {
expect(m.layoutProperties.get(`${layer}/visibility`)).toBe('visible')
}
})
it('leaves the layers standard keeps alone in the hidden sense, not the write sense', () => {
const m = liveSheet()
attachMapDetail(m as never, 'standard')
expect(m.layoutProperties.get(`${LIVE_TOPO_LAYER_IDS.boundary}/visibility`)).toBe(
'none',
)
expect(m.layoutProperties.get(`${LIVE_TOPO_LAYER_IDS.track}/visibility`)).toBe(
'visible',
)
})
it('rebuilds nothing - detail is visibility, never a style swap', () => {
const m = liveSheet()
attachMapDetail(m as never, 'minimal')
expect(m.styles).toEqual([])
})
it('skips the terrain layers a style built without a DEM does not have', () => {
// The probe is the wood layer; proving it exists proves nothing about the
// contour layers the no-terrain filter dropped, and the mock throws on a
// write to an absent layer exactly as MapLibre does.
const m = new MockMap({})
m.layerIds = [
LIVE_TOPO_LAYER_IDS.wood,
LIVE_TOPO_LAYER_IDS.boundary,
LIVE_TOPO_LAYER_IDS.track,
LIVE_TOPO_LAYER_IDS.roadMinor,
LIVE_TOPO_LAYER_IDS.waterLabel,
LIVE_TOPO_LAYER_IDS.scrub,
]
attachMapDetail(m as never, 'minimal')
expect(m.layoutProperties.get(`${LIVE_TOPO_LAYER_IDS.boundary}/visibility`)).toBe(
'none',
)
expect(
m.layoutProperties.get(`${LIVE_TOPO_LAYER_IDS.contour}/visibility`),
).toBeUndefined()
})
it('leaves an offline-background style alone', async () => {
// None of the sheet's layers is in it, which is a normal state rather
// than a failure - the wait simply never resolves and detach ends it.
const m = new MockMap({})
m.layerIds = ['backdrop', 'topo']
const detach = attachMapDetail(m as never, 'minimal')
m.emit('styledata')
detach()
expect(m.layoutProperties.size).toBe(0)
})
})