187 lines
5.0 KiB
Python
187 lines
5.0 KiB
Python
import importlib
|
|
import logging
|
|
import sys
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
import ray
|
|
from ray.widgets.util import _can_display_ipywidgets, repr_with_fallback
|
|
|
|
|
|
@pytest.fixture
|
|
def logs(propagate_logs, caplog):
|
|
"""A log fixture which captures logs during a test."""
|
|
caplog.set_level(logging.INFO)
|
|
return caplog
|
|
|
|
|
|
@pytest.fixture
|
|
def fancy_mimebundle():
|
|
return {
|
|
"fancy/mimetype": "A fancy repr",
|
|
"text/plain": "A simple repr",
|
|
}
|
|
|
|
|
|
@mock.patch.object(ray.widgets.util, "in_notebook")
|
|
@mock.patch.object(importlib.util, "find_spec")
|
|
@mock.patch("importlib.import_module")
|
|
def test_repr_with_fallback_missing(
|
|
mock_import_module,
|
|
mock_find_spec,
|
|
mock_in_notebook,
|
|
logs,
|
|
fancy_mimebundle,
|
|
):
|
|
"""Test that missing notebook dependencies trigger a log message."""
|
|
|
|
def raise_import_error(*args):
|
|
raise ImportError
|
|
|
|
mock_import_module.side_effect = raise_import_error
|
|
mock_find_spec.return_value = None
|
|
mock_in_notebook.return_value = True
|
|
|
|
class DummyObject:
|
|
def __repr__(self):
|
|
return "dummy repr"
|
|
|
|
@repr_with_fallback(["somedep", "8"])
|
|
def _repr_mimebundle_(self, **kwargs):
|
|
return fancy_mimebundle
|
|
|
|
result = DummyObject()._repr_mimebundle_()
|
|
assert result == {"text/plain": "dummy repr"}
|
|
assert "Missing packages:" in logs.records[-1].msg
|
|
|
|
|
|
@mock.patch.object(ray.widgets.util, "in_notebook")
|
|
@mock.patch.object(importlib.util, "find_spec")
|
|
@mock.patch("importlib.import_module")
|
|
def test_repr_with_fallback_outdated(
|
|
mock_import_module,
|
|
mock_find_spec,
|
|
mock_in_notebook,
|
|
logs,
|
|
fancy_mimebundle,
|
|
):
|
|
"""Test that outdated notebook dependencies trigger a log message."""
|
|
|
|
class MockDep:
|
|
__version__ = "7.0.0"
|
|
|
|
mock_import_module.return_value = MockDep()
|
|
mock_find_spec.return_value = "a valid import spec"
|
|
mock_in_notebook.return_value = True
|
|
|
|
class DummyObject:
|
|
def __repr__(self):
|
|
return "dummy repr"
|
|
|
|
@repr_with_fallback(["somedep", "8"])
|
|
def _repr_mimebundle_(self, **kwargs):
|
|
return fancy_mimebundle
|
|
|
|
result = DummyObject()._repr_mimebundle_()
|
|
assert result == {"text/plain": "dummy repr"}
|
|
assert "Outdated packages:" in logs.records[-1].msg
|
|
|
|
|
|
@mock.patch.object(ray.widgets.util, "_can_display_ipywidgets")
|
|
@mock.patch.object(importlib.util, "find_spec")
|
|
@mock.patch("importlib.import_module")
|
|
def test_repr_with_fallback_valid(
|
|
mock_import_module,
|
|
mock_find_spec,
|
|
mock_can_display_ipywidgets,
|
|
logs,
|
|
fancy_mimebundle,
|
|
):
|
|
"""Test that valid notebook dependencies don't trigger a log message."""
|
|
|
|
class MockDep:
|
|
__version__ = "8.0.0"
|
|
|
|
mock_import_module.return_value = MockDep()
|
|
mock_find_spec.return_value = "a valid import spec"
|
|
mock_can_display_ipywidgets.return_value = True
|
|
|
|
class DummyObject:
|
|
def __repr__(self):
|
|
return "dummy repr"
|
|
|
|
@repr_with_fallback(["somedep", "8"])
|
|
def _repr_mimebundle_(self, **kwargs):
|
|
return fancy_mimebundle
|
|
|
|
result = DummyObject()._repr_mimebundle_()
|
|
assert len(logs.records) == 0
|
|
assert result == fancy_mimebundle
|
|
|
|
|
|
@mock.patch.object(ray.widgets.util, "_can_display_ipywidgets")
|
|
@mock.patch.object(importlib.util, "find_spec")
|
|
@mock.patch("importlib.import_module")
|
|
def test_repr_with_fallback_invalid_shell(
|
|
mock_import_module,
|
|
mock_find_spec,
|
|
mock_can_display_ipywidgets,
|
|
logs,
|
|
fancy_mimebundle,
|
|
):
|
|
"""Test that the mimebundle is correctly stripped if run in an invalid shell."""
|
|
|
|
class MockDep:
|
|
__version__ = "8.0.0"
|
|
|
|
mock_import_module.return_value = MockDep()
|
|
mock_find_spec.return_value = "a valid import spec"
|
|
mock_can_display_ipywidgets.return_value = False
|
|
|
|
class DummyObject:
|
|
def __repr__(self):
|
|
return "dummy repr"
|
|
|
|
@repr_with_fallback(["somedep", "8"])
|
|
def _repr_mimebundle_(self, **kwargs):
|
|
return fancy_mimebundle
|
|
|
|
result = DummyObject()._repr_mimebundle_()
|
|
assert len(logs.records) == 0
|
|
assert result == {"text/plain": "dummy repr"}
|
|
|
|
|
|
@mock.patch.object(ray.widgets.util, "_get_ipython_shell_name")
|
|
@mock.patch.object(importlib.util, "find_spec")
|
|
@mock.patch("importlib.import_module")
|
|
@pytest.mark.parametrize(
|
|
"shell,can_display",
|
|
[
|
|
("ZMQInteractiveShell", True),
|
|
("google.colab.kernel", False),
|
|
("TerminalInteractiveShell", False),
|
|
("", False),
|
|
],
|
|
)
|
|
def test_can_display_ipywidgets(
|
|
mock_import_module,
|
|
mock_find_spec,
|
|
mock_get_ipython_shell_name,
|
|
shell,
|
|
can_display,
|
|
):
|
|
class MockDep:
|
|
__version__ = "8.0.0"
|
|
|
|
mock_import_module.return_value = MockDep()
|
|
mock_find_spec.return_value = "a valid import spec"
|
|
mock_get_ipython_shell_name.return_value = shell
|
|
|
|
assert _can_display_ipywidgets(["somedep", "8"], message="") == can_display
|
|
mock_get_ipython_shell_name.assert_called()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(pytest.main(["-v", __file__]))
|