Skip to content

Commit

Permalink
Part 1, modernize test suite (#5954)
Browse files Browse the repository at this point in the history
  • Loading branch information
hoxbro authored Nov 22, 2023
1 parent 2ae0bfd commit 982b51b
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 247 deletions.
3 changes: 2 additions & 1 deletion holoviews/core/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def encode(cls, entry):
@bothmethod
def _filename(self_or_cls, filename):
"Add the file extension if not already present"
filename = os.fspath(filename)
if not filename.endswith(self_or_cls.file_ext):
return f'{filename}.{self_or_cls.file_ext}'
else:
Expand Down Expand Up @@ -361,7 +362,7 @@ def save(self_or_cls, obj, filename, key=None, info=None, **kwargs):
info = self_or_cls._merge_metadata(obj, self_or_cls.info_fn, info, base_info)
compression = zipfile.ZIP_STORED if self_or_cls.compress else zipfile.ZIP_DEFLATED

filename = self_or_cls._filename(filename) if isinstance(filename, str) else filename
filename = self_or_cls._filename(filename) if isinstance(filename, (str, os.PathLike)) else filename
with zipfile.ZipFile(filename, 'w', compression=compression) as f:

if isinstance(obj, Layout) and not isinstance(obj, Overlay):
Expand Down
13 changes: 13 additions & 0 deletions holoviews/element/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,3 +777,16 @@ def __init__(self, *args, **kwargs):
registry = Comparison.register()
for k, v in registry.items():
self.addTypeEqualityFunc(k, v)


_assert_element_equal = ComparisonTestCase().assertEqual

def assert_element_equal(element1, element2):
# Filter non-holoviews elements
hv_types = (Element, Layout)
if not isinstance(element1, hv_types):
raise TypeError(f"First argument is not an allowed type but a {type(element1).__name__!r}.")
if not isinstance(element2, hv_types):
raise TypeError(f"Second argument is not an allowed type but a {type(element2).__name__!r}.")

_assert_element_equal(element1, element2)
1 change: 1 addition & 0 deletions holoviews/ipython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def setUp(self):
except Exception as e:
raise SkipTest("IPython could not be started") from e

self.ip.displayhook.flush = lambda: None # To avoid gc.collect called in it
self.addTypeEqualityFunc(HTML, self.skip_comparison)
self.addTypeEqualityFunc(SVG, self.skip_comparison)

Expand Down
30 changes: 30 additions & 0 deletions holoviews/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,33 @@ def ibis_sqlite_backend():
ibis.set_backend('sqlite')
yield
ibis.set_backend(None)


@pytest.fixture
def bokeh_backend():
import holoviews as hv
hv.renderer('bokeh')
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'bokeh'
yield
hv.Store.current_backend = prev_backend


@pytest.fixture
def mpl_backend():
import holoviews as hv
hv.renderer('matplotlib')
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'matplotlib'
yield
hv.Store.current_backend = prev_backend


@pytest.fixture
def plotly_backend():
import holoviews as hv
hv.renderer('plotly')
prev_backend = hv.Store.current_backend
hv.Store.current_backend = 'plotly'
yield
hv.Store.current_backend = prev_backend
129 changes: 58 additions & 71 deletions holoviews/tests/core/test_archives.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,138 +4,125 @@
"""
import json
import os
import shutil
import tarfile
import zipfile

import numpy as np

from holoviews import Image
from holoviews.core.io import FileArchive, Serializer
from holoviews.element.comparison import ComparisonTestCase


class TestFileArchive(ComparisonTestCase):
class TestFileArchive:

def setUp(self):
def setup_method(self):
self.image1 = Image(np.array([[1,2],[4,5]]), group='Group1', label='Im1')
self.image2 = Image(np.array([[5,4],[3,2]]), group='Group2', label='Im2')

def tearDown(self):
for f in os.listdir('.'):
if any(f.endswith(ext) for ext in ['.json', '.zip', '.tar']):
os.remove(f)
if os.path.isdir(f) and f.startswith('archive_'):
shutil.rmtree(f)

def test_filearchive_init(self):
FileArchive()

def test_filearchive_image_pickle(self):
def test_filearchive_image_pickle(self, tmp_path):
export_name = 'archive_image'
filenames = ['Group1-Im1.hvz', 'Group2-Im2.hvz']
archive = FileArchive(export_name=export_name, pack=False)
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name, pack=False)
archive.add(self.image1)
archive.add(self.image2)
self.assertEqual(len(archive), 2)
self.assertEqual(archive.listing(), filenames)
assert len(archive) == 2
assert archive.listing() == filenames
archive.export()
if not os.path.isdir(export_name):
raise AssertionError(f"No directory {export_name!r} created on export.")
self.assertEqual(sorted(filenames), sorted(os.listdir(export_name)))
self.assertEqual(archive.listing(), [])
assert os.path.isdir(tmp_path / export_name), f"No directory {str(export_name)!r} created on export."
assert sorted(filenames) == sorted(os.listdir(tmp_path / export_name))
assert archive.listing() == []

def test_filearchive_image_pickle_zip(self):
def test_filearchive_image_pickle_zip(self, tmp_path):
export_name = 'archive_image'
filenames = ['Group1-Im1.hvz', 'Group2-Im2.hvz']
archive = FileArchive(export_name=export_name,
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name,
pack=True, archive_format='zip')
archive.add(self.image1)
archive.add(self.image2)
self.assertEqual(len(archive), 2)
self.assertEqual(archive.listing(), filenames)
assert len(archive) == 2
assert archive.listing() == filenames
archive.export()
if not os.path.isfile(export_name+'.zip'):
raise AssertionError(f"No zip file {export_name!r} created on export.")

namelist = [f'archive_image/{f}' for f in filenames]
with zipfile.ZipFile(export_name+'.zip', 'r') as f:
self.assertEqual(sorted(namelist), sorted(f.namelist()))
self.assertEqual(archive.listing(), [])
export_folder = os.fspath(tmp_path / export_name) + '.zip'
assert os.path.isfile(export_folder)
namelist = [f'{export_name}/{f}' for f in filenames]
with zipfile.ZipFile(export_folder, 'r') as f:
expected = sorted(map(os.path.abspath, namelist))
output = sorted(map(os.path.abspath, f.namelist()))
assert expected == output
assert archive.listing() == []


def test_filearchive_image_pickle_tar(self):
def test_filearchive_image_pickle_tar(self, tmp_path):
export_name = 'archive_image'
filenames = ['Group1-Im1.hvz', 'Group2-Im2.hvz']
archive = FileArchive(export_name=export_name,
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name,
pack=True, archive_format='tar')
archive.add(self.image1)
archive.add(self.image2)
self.assertEqual(len(archive), 2)
self.assertEqual(archive.listing(), filenames)
assert len(archive) == 2
assert archive.listing() == filenames
archive.export()
if not os.path.isfile(export_name+'.tar'):
raise AssertionError(f"No tar file {export_name!r} created on export.")
export_folder = os.fspath(tmp_path / export_name) + '.tar'
assert os.path.isfile(export_folder)
namelist = [f'{export_name}/{f}' for f in filenames]
with tarfile.TarFile(export_folder, 'r') as f:
assert sorted(namelist) == sorted([el.path for el in f.getmembers()])
assert archive.listing() == []

namelist = [f'archive_image/{f}' for f in filenames]
with tarfile.TarFile(export_name+'.tar', 'r') as f:
self.assertEqual(sorted(namelist),
sorted([el.path for el in f.getmembers()]))
self.assertEqual(archive.listing(), [])


def test_filearchive_image_serialize(self):
def test_filearchive_image_serialize(self, tmp_path):
export_name = 'archive_image_serizalize'
filenames = ['Group1-Im1.pkl', 'Group2-Im2.pkl']
archive = FileArchive(export_name=export_name, exporters=[Serializer], pack=False)
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name, exporters=[Serializer], pack=False)
archive.add(self.image1)
archive.add(self.image2)
self.assertEqual(len(archive), 2)
self.assertEqual(archive.listing(), filenames)
assert len(archive) == 2
assert archive.listing() == filenames
archive.export()
if not os.path.isdir(export_name):
raise AssertionError(f"No directory {export_name!r} created on export.")
self.assertEqual(sorted(filenames), sorted(os.listdir(export_name)))
self.assertEqual(archive.listing(), [])
assert os.path.isdir(tmp_path / export_name)
assert sorted(filenames) == sorted(os.listdir(tmp_path / export_name))
assert archive.listing() == []

def test_filearchive_image_pickle_name_clash(self):
def test_filearchive_image_pickle_name_clash(self, tmp_path):
export_name = 'archive_image_test_clash'
filenames = ['Group1-Im1.hvz', 'Group1-Im1-1.hvz']
archive = FileArchive(export_name=export_name, pack=False)
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name, pack=False)
archive.add(self.image1)
archive.add(self.image1)
self.assertEqual(len(archive), 2)
self.assertEqual(archive.listing(), filenames)
assert len(archive) == 2
assert archive.listing() == filenames
archive.export()
if not os.path.isdir(export_name):
raise AssertionError(f"No directory {export_name!r} created on export.")
self.assertEqual(sorted(filenames), sorted(os.listdir(export_name)))
self.assertEqual(archive.listing(), [])
assert os.path.isdir(tmp_path / export_name)
assert sorted(filenames) == sorted(os.listdir(tmp_path / export_name))
assert archive.listing() == []

def test_filearchive_json_single_file(self):
export_name = 'archive_json'
def test_filearchive_json_single_file(self, tmp_path):
export_name = "archive_json"
data = {'meta':'test'}
archive = FileArchive(export_name=export_name, pack=False)
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name, pack=False)
archive.add(filename='metadata.json', data=json.dumps(data),
info={'mime_type':'text/json'})
self.assertEqual(len(archive), 1)
self.assertEqual(archive.listing(), ['metadata.json'])
assert len(archive) == 1
assert archive.listing() == ['metadata.json']
archive.export()
fname = f"{export_name}_metadata.json"
if not os.path.isfile(fname):
raise AssertionError(f"No file {fname!r} created on export.")
fname = os.fspath(tmp_path / f"{export_name}_metadata.json")
assert os.path.isfile(fname)
with open(fname) as f:
self.assertEqual(json.load(f), data)
self.assertEqual(archive.listing(), [])
assert json.load(f) == data
assert archive.listing() == []

"""
A test case that examines the clear() method of
FileArchives of io.py
"""
def test_filearchive_clear_file(self):
def test_filearchive_clear_file(self, tmp_path):
export_name = "archive_for_clear"
export_name = "archive_for_clear"
archive = FileArchive(export_name=export_name, pack=False)
archive = FileArchive(root=os.fspath(tmp_path), export_name=export_name, pack=False)
archive.add(self.image1)
archive.add(self.image2)
archive.clear()
self.assertEqual(archive._files, {})
assert archive._files == {}
Loading

0 comments on commit 982b51b

Please sign in to comment.