Skip to content

Commit f17b998

Browse files
committed
Increase coverage
1 parent 3c83bd7 commit f17b998

File tree

5 files changed

+87
-45
lines changed

5 files changed

+87
-45
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ jobs:
7171
numpy-version: '<2.0'
7272
- python-version: "3.13"
7373
pandas-version: pre
74-
polars: true
7574
- python-version: "3.13"
7675
uninstall_non_essential_dependencies: true
7776
- python-version: "3.10"
@@ -110,16 +109,12 @@ jobs:
110109
if: matrix.typeguard-version != 'latest'
111110
run: pip install 'typeguard${{ matrix.typeguard-version }}'
112111

113-
- name: Install polars
114-
if: matrix.polars
115-
run: pip install -e .[polars]
116-
117112
- name: Install shiny
118113
run: pip install "shiny>=1.0" shinywidgets
119114

120115
- name: Uninstall non-essential dependencies
121116
if: matrix.uninstall_non_essential_dependencies
122-
run: pip uninstall jinja2 dash anywidget streamlit shiny shinywidgets -y
117+
run: pip uninstall polars jinja2 dash anywidget streamlit shiny shinywidgets -y
123118

124119
- name: Install a Jupyter Kernel
125120
run: python -m ipykernel install --name itables --user

packages/dt_for_itables/add_host_to_root.py

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,31 +61,21 @@ def process_rule(match):
6161
return re.sub(pattern, process_rule, css_content)
6262

6363

64-
if __name__ == "__main__":
65-
66-
def main():
67-
parser = argparse.ArgumentParser(
68-
description="Add :host to each :root selector in a CSS file."
69-
)
70-
parser.add_argument("css_file", help="Path to the CSS file to modify")
71-
args = parser.parse_args()
64+
def main(argv):
65+
parser = argparse.ArgumentParser(
66+
description="Add :host to each :root selector in a CSS file."
67+
)
68+
parser.add_argument("css_file", help="Path to the CSS file to modify")
69+
args = parser.parse_args(argv[1:])
7270

73-
try:
74-
with open(args.css_file, "r") as file:
75-
css_content = file.read()
71+
with open(args.css_file, "r") as file:
72+
css_content = file.read()
7673

77-
modified_content = add_host_to_root(css_content)
74+
modified_content = add_host_to_root(css_content)
7875

79-
with open(args.css_file, "w") as file:
80-
file.write(modified_content)
76+
with open(args.css_file, "w") as file:
77+
file.write(modified_content)
8178

82-
print(f"Successfully updated {args.css_file}")
83-
return 0
84-
except FileNotFoundError:
85-
print(f"Error: File {args.css_file} not found.")
86-
return 1
87-
except Exception as e:
88-
print(f"Error processing file: {e}")
89-
return 1
9079

91-
sys.exit(main())
80+
if __name__ == "__main__":
81+
sys.exit(main(sys.argv))

packages/dt_for_itables/test_add_host_to_root.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from add_host_to_root import add_host_to_root
2+
from add_host_to_root import add_host_to_root, main
33

44

55
def test_add_host_to_root_example():
@@ -66,3 +66,15 @@ def test_add_host_to_root_complex_selectors():
6666
:root[data-theme="light"] .element, :host[data-theme="light"] .element { background-color: white; }
6767
"""
6868
assert add_host_to_root(original_css) == expected_css
69+
70+
71+
def test_main_function(tmp_path):
72+
"""Test the main function modifies the file as expected."""
73+
css_content = ":root { color: red; }"
74+
expected_content = ":root, :host { color: red; }"
75+
css_file = tmp_path / "test.css"
76+
css_file.write_text(css_content)
77+
78+
main(["add_host_to_root.py", str(css_file)])
79+
result = css_file.read_text()
80+
assert result == expected_content

tests/test_apps.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import subprocess
2+
import sys
3+
from pathlib import Path
4+
5+
import pytest
6+
7+
APP_FOLDER = Path(__file__).parent.parent / "apps"
8+
APP_FILES = list(APP_FOLDER.glob("**/*.py"))
9+
assert APP_FILES, APP_FOLDER
10+
11+
12+
@pytest.fixture(params=APP_FILES, ids=lambda p: str(p.relative_to(APP_FOLDER)))
13+
def app_file(request):
14+
return request.param
15+
16+
17+
def test_app_can_be_imported(app_file: Path):
18+
app_name = str(app_file.relative_to(APP_FOLDER))
19+
framework = app_file.relative_to(APP_FOLDER).parts[0]
20+
if framework == "shiny":
21+
pytest.importorskip("shiny")
22+
if framework == "streamlit":
23+
pytest.importorskip("streamlit")
24+
if framework == "dash":
25+
pytest.importorskip("dash")
26+
27+
is_shiny_app = framework == "shiny" and app_name.endswith("app.py")
28+
29+
code = f"""
30+
import importlib.util
31+
32+
spec = importlib.util.spec_from_file_location("{app_file.stem}", "{app_file}")
33+
assert spec is not None
34+
module = importlib.util.module_from_spec(spec)
35+
assert spec.loader is not None
36+
37+
try:
38+
spec.loader.exec_module(module)
39+
except RuntimeError:
40+
# In Shiny apps we expect this error:
41+
# RuntimeError: express.ui.page_opts() can only be used inside of a standalone Shiny Express app.
42+
if not {is_shiny_app}:
43+
raise
44+
"""
45+
46+
result = subprocess.run(
47+
[sys.executable, "-c", code], capture_output=True, text=True
48+
)
49+
assert result.returncode == 0, result.stderr

tests/test_documentation_notebooks_run.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import subprocess
2+
import sys
13
from pathlib import Path
24

35
import jupytext
46
import pytest
57

6-
import itables.options as opt
7-
from itables import init_notebook_mode
88
from itables.javascript import pd_style
99

1010
try:
@@ -34,20 +34,16 @@ def test_run_documentation_notebooks(notebook):
3434
pytest.skip("Polars is not available")
3535
if "pandas_style" in notebook.stem and pd_style is None:
3636
pytest.skip("Pandas Style is not available")
37-
if "shiny" in notebook.stem:
38-
pytest.skip("shinywidgets makes the widget.md notebook fail")
39-
if "marimo" in notebook.stem or "widget" in notebook.stem:
37+
if (
38+
"shiny" in notebook.stem
39+
or "marimo" in notebook.stem
40+
or "widget" in notebook.stem
41+
):
4042
pytest.importorskip("anywidget")
4143

42-
org_options = dir(opt)
43-
4444
nb = jupytext.read(notebook)
4545
py_notebook = jupytext.writes(nb, "py:percent")
46-
exec(py_notebook, {})
47-
48-
new_options = set(dir(opt)).difference(org_options)
49-
for name in new_options:
50-
delattr(opt, name)
51-
52-
# Revert back to the non initialized mode
53-
init_notebook_mode(all_interactive=False, connected=True)
46+
result = subprocess.run(
47+
[sys.executable, "-c", py_notebook], capture_output=True, text=True
48+
)
49+
assert result.returncode == 0, result.stderr

0 commit comments

Comments
 (0)