Skip to content

Commit

Permalink
fix(typing): Resolve test_magics
Browse files Browse the repository at this point in the history
- Uses standardised import checking/skipping
- Imports `InteractiveShell` from the module
- Replaces global scope with fixtures
  • Loading branch information
dangotbanned committed Nov 5, 2024
1 parent 8ff3456 commit 2ab9dbf
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 54 deletions.
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,5 @@ ignore=[
"./sphinxext/",
"./tests/test_jupyter_chart.py",
"./tests/utils/",
"./tests/test_magics.py",
"../../../**/Lib", # stdlib
]
11 changes: 11 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ def windows_has_tzdata() -> bool:
>>> hatch run test-slow --durations=25 # doctest: +SKIP
"""

skip_requires_ipython: pytest.MarkDecorator = pytest.mark.skipif(
find_spec("IPython") is None, reason="`IPython` not installed."
)
"""
``pytest.mark.skipif`` decorator.
Applies when `IPython`_ import would fail.
.. _IPython:
/~https://github.com/ipython/ipython
"""

skip_requires_vl_convert: pytest.MarkDecorator = pytest.mark.skipif(
find_spec("vl_convert") is None, reason="`vl_convert` not installed."
Expand Down
114 changes: 61 additions & 53 deletions tests/test_magics.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,76 @@
from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any

import pytest

try:
from IPython import InteractiveShell

IPYTHON_AVAILABLE = True
except ImportError:
IPYTHON_AVAILABLE = False

from altair.vegalite.v5 import VegaLite

DATA_RECORDS = [
{"amount": 28, "category": "A"},
{"amount": 55, "category": "B"},
{"amount": 43, "category": "C"},
{"amount": 91, "category": "D"},
{"amount": 81, "category": "E"},
{"amount": 53, "category": "F"},
{"amount": 19, "category": "G"},
{"amount": 87, "category": "H"},
]

if IPYTHON_AVAILABLE:
_ipshell = InteractiveShell.instance()
_ipshell.run_cell("%load_ext altair")
_ipshell.run_cell(
f"""
import pandas as pd
table = pd.DataFrame.from_records({DATA_RECORDS})
the_data = table
"""
)
from altair.vegalite.v5.display import VegaLite
from tests import skip_requires_ipython

if TYPE_CHECKING:
from IPython.core.interactiveshell import InteractiveShell


@pytest.fixture
def records() -> list[dict[str, Any]]:
return [
{"amount": 28, "category": "A"},
{"amount": 55, "category": "B"},
{"amount": 43, "category": "C"},
{"amount": 91, "category": "D"},
{"amount": 81, "category": "E"},
{"amount": 53, "category": "F"},
{"amount": 19, "category": "G"},
{"amount": 87, "category": "H"},
]


VEGALITE_SPEC = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"values": DATA_RECORDS},
"description": "A simple bar chart with embedded data.",
"encoding": {
"x": {"field": "category", "type": "ordinal"},
"y": {"field": "amount", "type": "quantitative"},
},
"mark": {"type": "bar"},
}
@pytest.fixture
def vl_spec(records) -> dict[str, Any]:
return {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"values": records},
"description": "A simple bar chart with embedded data.",
"encoding": {
"x": {"field": "category", "type": "ordinal"},
"y": {"field": "amount", "type": "quantitative"},
},
"mark": {"type": "bar"},
}


@pytest.fixture
def ipshell(records) -> InteractiveShell:
from IPython.core.interactiveshell import InteractiveShell

shell = InteractiveShell.instance()
shell.run_cell("%load_ext altair")
shell.run_cell(
f"import pandas as pd\n"
f"table = pd.DataFrame.from_records({records})\n"
f"the_data = table"
)
return shell


@pytest.mark.skipif(not IPYTHON_AVAILABLE, reason="requires ipython")
def test_vegalite_magic_data_included():
result = _ipshell.run_cell("%%vegalite\n" + json.dumps(VEGALITE_SPEC))
@skip_requires_ipython
def test_vegalite_magic_data_included(ipshell, vl_spec) -> None:
result = ipshell.run_cell("%%vegalite\n" + json.dumps(vl_spec))
assert isinstance(result.result, VegaLite)
assert result.result.spec == VEGALITE_SPEC
assert result.result.spec == vl_spec


@pytest.mark.skipif(not IPYTHON_AVAILABLE, reason="requires ipython")
def test_vegalite_magic_json_flag():
result = _ipshell.run_cell("%%vegalite --json\n" + json.dumps(VEGALITE_SPEC))
@skip_requires_ipython
def test_vegalite_magic_json_flag(ipshell, vl_spec) -> None:
result = ipshell.run_cell("%%vegalite --json\n" + json.dumps(vl_spec))
assert isinstance(result.result, VegaLite)
assert result.result.spec == VEGALITE_SPEC
assert result.result.spec == vl_spec


@pytest.mark.skipif(not IPYTHON_AVAILABLE, reason="requires ipython")
def test_vegalite_magic_pandas_data():
spec = {key: val for key, val in VEGALITE_SPEC.items() if key != "data"}
result = _ipshell.run_cell("%%vegalite table\n" + json.dumps(spec))
@skip_requires_ipython
def test_vegalite_magic_pandas_data(ipshell, vl_spec) -> None:
spec = {key: val for key, val in vl_spec.items() if key != "data"}
result = ipshell.run_cell("%%vegalite table\n" + json.dumps(spec))
assert isinstance(result.result, VegaLite)
assert result.result.spec == VEGALITE_SPEC
assert result.result.spec == vl_spec

0 comments on commit 2ab9dbf

Please sign in to comment.