Skip to content

Commit a681c84

Browse files
committed
update kaleido tests to support kaleido v1
1 parent f0a78a6 commit a681c84

File tree

1 file changed

+63
-112
lines changed

1 file changed

+63
-112
lines changed

tests/test_optional/test_kaleido/test_kaleido.py

Lines changed: 63 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,31 @@
1-
import plotly.io as pio
2-
import plotly.io.kaleido
3-
from contextlib import contextmanager
41
from io import BytesIO
52
from pathlib import Path
6-
from unittest.mock import Mock
7-
8-
fig = {"layout": {"title": {"text": "figure title"}}}
9-
10-
11-
def make_writeable_mocks():
12-
"""Produce some mocks which we will use for testing the `write_image()` function.
13-
14-
These mocks should be passed as the `file=` argument to `write_image()`.
15-
16-
The tests should verify that the method specified in the `active_write_function`
17-
attribute is called once, and that scope.transform is called with the `format=`
18-
argument specified by the `.expected_format` attribute.
19-
20-
In total we provide two mocks: one for a writable file descriptor, and other for a
21-
pathlib.Path object.
22-
"""
23-
24-
# Part 1: A mock for a file descriptor
25-
# ------------------------------------
26-
mock_file_descriptor = Mock()
3+
import tempfile
274

28-
# A file descriptor has no write_bytes method, unlike a pathlib Path.
29-
del mock_file_descriptor.write_bytes
30-
31-
# The expected write method for a file descriptor is .write
32-
mock_file_descriptor.active_write_function = mock_file_descriptor.write
33-
34-
# Since there is no filename, there should be no format detected.
35-
mock_file_descriptor.expected_format = None
36-
37-
# Part 2: A mock for a pathlib path
38-
# ---------------------------------
39-
mock_pathlib_path = Mock(spec=Path)
40-
41-
# A pathlib Path object has no write method, unlike a file descriptor.
42-
del mock_pathlib_path.write
43-
44-
# The expected write method for a pathlib Path is .write_bytes
45-
mock_pathlib_path.active_write_function = mock_pathlib_path.write_bytes
46-
47-
# Mock a path with PNG suffix
48-
mock_pathlib_path.suffix = ".png"
49-
mock_pathlib_path.expected_format = "png"
5+
from pdfrw import PdfReader
6+
from PIL import Image
7+
import plotly.io as pio
508

51-
return mock_file_descriptor, mock_pathlib_path
9+
fig = {"data": [], "layout": {"title": {"text": "figure title"}}}
5210

5311

54-
@contextmanager
55-
def mocked_scope():
56-
# Code to acquire resource, e.g.:
57-
scope_mock = Mock()
58-
original_scope = pio._kaleido.scope
59-
pio._kaleido.scope = scope_mock
60-
try:
61-
yield scope_mock
62-
finally:
63-
pio._kaleido.scope = original_scope
12+
def check_image(path_or_buffer, size=(700, 500), format="PNG"):
13+
if format == "PDF":
14+
img = PdfReader(path_or_buffer)
15+
# TODO: There is a conversion factor needed here
16+
# In Kaleido v0 the conversion factor is 0.75
17+
factor = 0.75
18+
expected_size = tuple(int(s * factor) for s in size)
19+
actual_size = tuple(int(s) for s in img.pages[0].MediaBox[2:])
20+
assert actual_size == expected_size
21+
else:
22+
if isinstance(path_or_buffer, (str, Path)):
23+
with open(path_or_buffer, "rb") as f:
24+
img = Image.open(f)
25+
else:
26+
img = Image.open(path_or_buffer)
27+
assert img.size == size
28+
assert img.format == format
6429

6530

6631
def test_kaleido_engine_to_image_returns_bytes():
@@ -75,80 +40,66 @@ def test_kaleido_fulljson():
7540

7641

7742
def test_kaleido_engine_to_image():
78-
with mocked_scope() as scope:
79-
pio.to_image(fig, engine="kaleido", validate=False)
43+
bytes = pio.to_image(fig, engine="kaleido", validate=False)
8044

81-
scope.transform.assert_called_with(
82-
fig, format=None, width=None, height=None, scale=None
83-
)
45+
# Check that image dimensions match default dimensions (700x500)
46+
# and format is default format (png)
47+
check_image(BytesIO(bytes))
8448

8549

86-
def test_kaleido_engine_write_image():
87-
for writeable_mock in make_writeable_mocks():
88-
with mocked_scope() as scope:
89-
pio.write_image(fig, writeable_mock, engine="kaleido", validate=False)
50+
def test_kaleido_engine_write_image(tmp_path):
51+
path_str = tempfile.mkstemp(suffix=".png", dir=tmp_path)[1]
52+
path_path = Path(tempfile.mkstemp(suffix=".png", dir=tmp_path)[1])
9053

91-
scope.transform.assert_called_with(
92-
fig,
93-
format=writeable_mock.expected_format,
94-
width=None,
95-
height=None,
96-
scale=None,
97-
)
98-
99-
assert writeable_mock.active_write_function.call_count == 1
54+
for out_path in [path_str, path_path]:
55+
pio.write_image(fig, out_path, engine="kaleido", validate=False)
56+
check_image(out_path)
10057

10158

10259
def test_kaleido_engine_to_image_kwargs():
103-
with mocked_scope() as scope:
104-
pio.to_image(
60+
bytes = pio.to_image(
61+
fig,
62+
format="pdf",
63+
width=700,
64+
height=600,
65+
scale=2,
66+
engine="kaleido",
67+
validate=False,
68+
)
69+
check_image(BytesIO(bytes), size=(700 * 2, 600 * 2), format="PDF")
70+
71+
72+
def test_kaleido_engine_write_image_kwargs(tmp_path):
73+
path_str = tempfile.mkstemp(suffix=".png", dir=tmp_path)[1]
74+
path_path = Path(tempfile.mkstemp(suffix=".png", dir=tmp_path)[1])
75+
76+
for out_path in [path_str, path_path]:
77+
pio.write_image(
10578
fig,
106-
format="pdf",
79+
out_path,
80+
format="jpg",
10781
width=700,
10882
height=600,
10983
scale=2,
11084
engine="kaleido",
11185
validate=False,
11286
)
113-
114-
scope.transform.assert_called_with(
115-
fig, format="pdf", width=700, height=600, scale=2
116-
)
117-
118-
119-
def test_kaleido_engine_write_image_kwargs():
120-
for writeable_mock in make_writeable_mocks():
121-
with mocked_scope() as scope:
122-
pio.write_image(
123-
fig,
124-
writeable_mock,
125-
format="jpg",
126-
width=700,
127-
height=600,
128-
scale=2,
129-
engine="kaleido",
130-
validate=False,
131-
)
132-
133-
scope.transform.assert_called_with(
134-
fig, format="jpg", width=700, height=600, scale=2
135-
)
136-
137-
assert writeable_mock.active_write_function.call_count == 1
87+
check_image(out_path, size=(700 * 2, 600 * 2), format="JPEG")
13888

13989

14090
def test_image_renderer():
141-
with mocked_scope() as scope:
142-
pio.show(fig, renderer="svg", engine="kaleido", validate=False)
91+
# TODO: How to replicate this test using kaleido v1?
92+
# with mocked_scope() as scope:
93+
pio.show(fig, renderer="svg", engine="kaleido", validate=False)
14394

14495
renderer = pio.renderers["svg"]
145-
scope.transform.assert_called_with(
146-
fig,
147-
format="svg",
148-
width=None,
149-
height=None,
150-
scale=renderer.scale,
151-
)
96+
# scope.transform.assert_called_with(
97+
# fig,
98+
# format="svg",
99+
# width=None,
100+
# height=None,
101+
# scale=renderer.scale,
102+
# )
152103

153104

154105
def test_bytesio():

0 commit comments

Comments
 (0)