Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
python-visualization
GitHub Repository: python-visualization/folium
Path: blob/main/tests/test_map.py
1593 views
1
"""
2
Folium map Tests
3
----------------
4
5
"""
6
7
import warnings
8
9
import numpy as np
10
import pytest
11
12
from folium import GeoJson, Map, TileLayer
13
from folium.map import Class, CustomPane, Icon, LayerControl, Marker, Popup
14
from folium.utilities import JsCode, normalize
15
16
tmpl = """
17
<div id="{id}"
18
style="width: {width}; height: {height};">
19
{text}</div>
20
""".format
21
22
23
def test_layer_control_initialization():
24
layer_control = LayerControl()
25
assert layer_control._name == "LayerControl"
26
assert layer_control.options["position"] == "topright"
27
assert layer_control.options["collapsed"] is True
28
assert layer_control.options["autoZIndex"] is True
29
assert layer_control.draggable is False
30
assert layer_control.base_layers == {}
31
assert layer_control.overlays == {}
32
33
34
def test_layer_control_reset():
35
layer_control = LayerControl()
36
layer_control.base_layers = {"Layer1": "layer1"}
37
layer_control.overlays = {"Layer2": "layer2"}
38
layer_control.reset()
39
assert layer_control.base_layers == {}
40
assert layer_control.overlays == {}
41
42
43
def test_layer_control_render():
44
m = Map(tiles=None)
45
layer1 = TileLayer().add_to(m)
46
layer2 = Marker([0, 0]).add_to(m)
47
layer3 = GeoJson({}).add_to(m)
48
layer1.control = True
49
layer2.control = False
50
layer3.control = True
51
layer1.layer_name = "Layer1"
52
layer2.layer_name = "Layer2"
53
layer3.layer_name = "Layer3"
54
layer1.get_name = lambda: "layer1"
55
layer2.get_name = lambda: "layer2"
56
layer3.get_name = lambda: "layer3"
57
58
layer_control = LayerControl().add_to(m)
59
layer_control.render()
60
61
assert layer_control.base_layers == {"Layer1": "layer1"}
62
assert layer_control.overlays == {"Layer3": "layer3"}
63
64
65
def test_layer_control_draggable():
66
m = Map(tiles=None)
67
layer_control = LayerControl(draggable=True).add_to(m)
68
expected = f"new L.Draggable({ layer_control.get_name() }.getContainer()).enable();"
69
rendered = m.get_root().render()
70
assert normalize(expected) in normalize(rendered)
71
72
73
def test_popup_ascii():
74
popup = Popup("Some text.")
75
_id = list(popup.html._children.keys())[0]
76
kw = {
77
"id": _id,
78
"width": "100.0%",
79
"height": "100.0%",
80
"text": "Some text.",
81
}
82
assert "".join(popup.html.render().split()) == "".join(tmpl(**kw).split())
83
84
85
def test_popup_quotes():
86
popup = Popup("Let's try quotes", parse_html=True)
87
_id = list(popup.html._children.keys())[0]
88
kw = {
89
"id": _id,
90
"width": "100.0%",
91
"height": "100.0%",
92
"text": "Let&#39;s try quotes",
93
}
94
assert "".join(popup.html.render().split()) == "".join(tmpl(**kw).split())
95
96
97
def test_popup_unicode():
98
popup = Popup("Ça c'est chouette", parse_html=True)
99
_id = list(popup.html._children.keys())[0]
100
kw = {
101
"id": _id,
102
"width": "100.0%",
103
"height": "100.0%",
104
"text": "Ça c&#39;est chouette",
105
}
106
assert "".join(popup.html.render().split()) == "".join(tmpl(**kw).split())
107
108
109
def test_popup_sticky():
110
m = Map()
111
popup = Popup("Some text.", sticky=True).add_to(m)
112
rendered = popup._template.render(this=popup, kwargs={})
113
expected = """
114
var {popup_name} = L.popup({{
115
"maxWidth": "100%",
116
"autoClose": false,
117
"closeOnClick": false,
118
}});
119
120
var {html_name} = $(`<div id="{html_name}" style="width: 100.0%; height: 100.0%;">Some text.</div>`)[0];
121
{popup_name}.setContent({html_name});
122
{map_name}.bindPopup({popup_name});
123
""".format(
124
popup_name=popup.get_name(),
125
html_name=list(popup.html._children.keys())[0],
126
map_name=m.get_name(),
127
)
128
assert normalize(rendered) == normalize(expected)
129
130
131
def test_popup_show():
132
m = Map()
133
popup = Popup("Some text.", show=True).add_to(m)
134
rendered = popup._template.render(this=popup, kwargs={})
135
expected = """
136
var {popup_name} = L.popup({{
137
"maxWidth": "100%","autoClose": false,
138
}});
139
var {html_name} = $(`<div id="{html_name}" style="width: 100.0%; height: 100.0%;">Some text.</div>`)[0];
140
{popup_name}.setContent({html_name});
141
{map_name}.bindPopup({popup_name}).openPopup();
142
""".format(
143
popup_name=popup.get_name(),
144
html_name=list(popup.html._children.keys())[0],
145
map_name=m.get_name(),
146
)
147
# assert compare_rendered(rendered, expected)
148
assert normalize(rendered) == normalize(expected)
149
150
151
def test_include():
152
create_tile = """
153
function(coords, done) {
154
const url = this.getTileUrl(coords);
155
const img = document.createElement('img');
156
fetch(url, {
157
headers: {
158
"Authorization": "Bearer <Token>"
159
},
160
})
161
.then((response) => {
162
img.src = URL.createObjectURL(response.body);
163
done(null, img);
164
})
165
return img;
166
}
167
"""
168
TileLayer.include(create_tile=JsCode(create_tile))
169
tiles = TileLayer(
170
tiles="OpenStreetMap",
171
)
172
m = Map(
173
tiles=tiles,
174
)
175
rendered = m.get_root().render()
176
Class._includes.clear()
177
expected = """
178
L.TileLayer.include({
179
"createTile":
180
function(coords, done) {
181
const url = this.getTileUrl(coords);
182
const img = document.createElement('img');
183
fetch(url, {
184
headers: {
185
"Authorization": "Bearer <Token>"
186
},
187
})
188
.then((response) => {
189
img.src = URL.createObjectURL(response.body);
190
done(null, img);
191
})
192
return img;
193
},
194
})
195
"""
196
assert normalize(expected) in normalize(rendered)
197
198
199
def test_include_once():
200
abc = "MY BEAUTIFUL SENTINEL"
201
TileLayer.include(abc=abc)
202
tiles = TileLayer(
203
tiles="OpenStreetMap",
204
)
205
m = Map(
206
tiles=tiles,
207
)
208
TileLayer(
209
tiles="OpenStreetMap",
210
).add_to(m)
211
212
rendered = m.get_root().render()
213
Class._includes.clear()
214
215
assert rendered.count(abc) == 1, "Includes should happen only once per class"
216
217
218
def test_popup_backticks():
219
m = Map()
220
popup = Popup("back`tick`tick").add_to(m)
221
rendered = popup._template.render(this=popup, kwargs={})
222
expected = """
223
var {popup_name} = L.popup({{
224
"maxWidth": "100%",
225
}});
226
var {html_name} = $(`<div id="{html_name}" style="width: 100.0%; height: 100.0%;">back\\`tick\\`tick</div>`)[0];
227
{popup_name}.setContent({html_name});
228
{map_name}.bindPopup({popup_name});
229
""".format(
230
popup_name=popup.get_name(),
231
html_name=list(popup.html._children.keys())[0],
232
map_name=m.get_name(),
233
)
234
assert normalize(rendered) == normalize(expected)
235
236
237
def test_popup_backticks_already_escaped():
238
m = Map()
239
popup = Popup("back\\`tick").add_to(m)
240
rendered = popup._template.render(this=popup, kwargs={})
241
expected = """
242
var {popup_name} = L.popup({{
243
"maxWidth": "100%",
244
}});
245
var {html_name} = $(`<div id="{html_name}" style="width: 100.0%; height: 100.0%;">back\\`tick</div>`)[0];
246
{popup_name}.setContent({html_name});
247
{map_name}.bindPopup({popup_name});
248
""".format(
249
popup_name=popup.get_name(),
250
html_name=list(popup.html._children.keys())[0],
251
map_name=m.get_name(),
252
)
253
assert normalize(rendered) == normalize(expected)
254
255
256
def test_icon_valid_marker_colors():
257
assert len(Icon.color_options) == 19
258
with warnings.catch_warnings():
259
warnings.simplefilter("error")
260
for color in Icon.color_options:
261
Icon(color=color)
262
263
264
def test_custom_pane_show():
265
m = Map()
266
pane = CustomPane("test-name", z_index=625, pointer_events=False).add_to(m)
267
rendered = pane._template.module.script(this=pane, kwargs={})
268
expected = f"""
269
var {pane.get_name()} = {m.get_name()}.createPane("test-name");
270
{pane.get_name()}.style.zIndex = 625;
271
{pane.get_name()}.style.pointerEvents = 'none';
272
"""
273
assert normalize(rendered) == normalize(expected)
274
275
276
def test_marker_valid_location():
277
m = Map()
278
marker = Marker()
279
marker.add_to(m)
280
with pytest.raises(ValueError):
281
m.render()
282
283
284
def test_marker_numpy_array_as_location():
285
Marker(np.array([0, 0]))
286
287
288
@pytest.mark.filterwarnings("ignore::UserWarning")
289
def test_icon_invalid_marker_colors():
290
pytest.warns(UserWarning, Icon, color="lila")
291
pytest.warns(UserWarning, Icon, color=42)
292
pytest.warns(UserWarning, Icon, color=None)
293
294