Skip to content

Commit

Permalink
Test vl-convert engine in chart.save test (#2784)
Browse files Browse the repository at this point in the history
* Explicitly pass engine argument through save function

* Update test_save to test both altair_saver and vl-convert engiens

* flake8
  • Loading branch information
jonmmease authored Dec 30, 2022
1 parent f288e2d commit 8c04fd7
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
7 changes: 6 additions & 1 deletion altair/utils/mimebundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def spec_to_mimebundle(
vega_version=None,
vegaembed_version=None,
vegalite_version=None,
engine=None,
**kwargs,
):
"""Convert a vega/vega-lite specification to a mimebundle
Expand All @@ -30,6 +31,8 @@ def spec_to_mimebundle(
The version of vegaembed.js to use
vegalite_version : string
The version of vegalite.js to use. Only required if mode=='vega-lite'
engine: string {'vl-convert', 'altair_saver'}
the conversion engine to use for 'png', 'svg', 'pdf', and 'vega' formats
**kwargs :
Additional arguments will be passed to the generating function
Expand All @@ -51,7 +54,9 @@ def spec_to_mimebundle(
raise ValueError("Must specify vega_version")
return {"application/vnd.vega.v{}+json".format(vega_version[0]): spec}
if format in ["png", "svg", "pdf", "vega"]:
return _spec_to_mimebundle_with_engine(spec, format, mode, **kwargs)
return _spec_to_mimebundle_with_engine(
spec, format, mode, engine=engine, **kwargs
)
if format == "html":
html = spec_to_html(
spec,
Expand Down
6 changes: 5 additions & 1 deletion altair/utils/save.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def save(
json_kwds=None,
webdriver=None,
scale_factor=1,
engine=None,
**kwargs,
):
"""Save a chart to file in a variety of formats
Expand Down Expand Up @@ -61,6 +62,8 @@ def save(
Webdriver to use for png or svg output
scale_factor : float (optional)
scale_factor to use to change size/resolution of png or svg output
engine: string {'vl-convert', 'altair_saver'}
the conversion engine to use for 'png', 'svg', and 'pdf' formats
**kwargs :
additional kwargs passed to spec_to_mimebundle.
"""
Expand Down Expand Up @@ -122,6 +125,7 @@ def save(
vegaembed_version=vegaembed_version,
webdriver=webdriver,
scale_factor=scale_factor,
engine=engine,
**kwargs,
)
if format == "png":
Expand All @@ -131,4 +135,4 @@ def save(
else:
write_file_or_filename(fp, mimebundle["image/svg+xml"], mode="w")
else:
raise ValueError("unrecognized format: '{}'".format(format))
raise ValueError("Unsupported format: '{}'".format(format))
74 changes: 55 additions & 19 deletions altair/vegalite/v5/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
except ImportError:
altair_saver = None

try:
import vl_convert as vlc # noqa: F401
except ImportError:
vlc = None


def getargs(*args, **kwargs):
return args, kwargs
Expand Down Expand Up @@ -253,45 +258,76 @@ def test_selection_expression():
selection.__magic__


@pytest.mark.parametrize("format", ["html", "json", "png", "svg", "pdf"])
def test_save(format, basic_chart):
@pytest.mark.parametrize("format", ["html", "json", "png", "svg", "pdf", "bogus"])
@pytest.mark.parametrize("engine", ["altair_saver", "vl-convert"])
def test_save(format, engine, basic_chart):
if format in ["pdf", "png"]:
out = io.BytesIO()
mode = "rb"
else:
out = io.StringIO()
mode = "r"

if format in ["svg", "png", "pdf"]:
if not altair_saver:
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format)
assert "github.com/altair-viz/altair_saver" in str(err.value)
return
elif format not in altair_saver.available_formats():
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format)
assert f"No enabled saver found that supports format='{format}'" in str(
err.value
)
return

basic_chart.save(out, format=format)
if format in ["svg", "png", "pdf", "bogus"]:
if engine == "altair_saver":
if altair_saver is None:
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert "altair_saver" in str(err.value)
return
elif format == "bogus":
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert f"Unsupported format: '{format}'" in str(err.value)
return
elif format not in altair_saver.available_formats():
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert f"No enabled saver found that supports format='{format}'" in str(
err.value
)
return

elif engine == "vl-convert":
if vlc is None:
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert "vl-convert-python" in str(err.value)
return
elif format == "pdf":
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert (
f"The 'vl-convert' conversion engine does not support the '{format}' format"
in str(err.value)
)
return
elif format not in ("png", "svg"):
with pytest.raises(ValueError) as err:
basic_chart.save(out, format=format, engine=engine)
assert f"Unsupported format: '{format}'" in str(err.value)
return

basic_chart.save(out, format=format, engine=engine)
out.seek(0)
content = out.read()

if format == "json":
assert "$schema" in json.loads(content)
if format == "html":
elif format == "html":
assert content.startswith("<!DOCTYPE html>")
elif format == "svg":
assert content.startswith("<svg")
elif format == "png":
assert content.startswith(b"\x89PNG")

fid, filename = tempfile.mkstemp(suffix="." + format)
os.close(fid)

# test both string filenames and pathlib.Paths
for fp in [filename, pathlib.Path(filename)]:
try:
basic_chart.save(fp)
basic_chart.save(fp, format=format, engine=engine)
with open(fp, mode) as f:
assert f.read()[:1000] == content[:1000]
finally:
Expand Down

0 comments on commit 8c04fd7

Please sign in to comment.