Skip to content

Commit e2eb5c7

Browse files
committed
Increase coverage
1 parent 3c83bd7 commit e2eb5c7

File tree

4 files changed

+70
-30
lines changed

4 files changed

+70
-30
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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import importlib.util
2+
from pathlib import Path
3+
4+
import pytest
5+
6+
from itables.widget import ITable
7+
8+
APP_FOLDER = Path(__file__).parent.parent / "apps"
9+
APP_FILES = list(APP_FOLDER.glob("**/*.py"))
10+
assert APP_FILES, APP_FOLDER
11+
12+
13+
@pytest.fixture(params=APP_FILES, ids=lambda p: str(p.relative_to(APP_FOLDER)))
14+
def app_file(request):
15+
return request.param
16+
17+
18+
def test_app_can_be_imported(app_file: Path):
19+
app_name = str(app_file.relative_to(APP_FOLDER))
20+
spec = importlib.util.spec_from_file_location(app_file.stem, app_file)
21+
assert spec is not None
22+
module = importlib.util.module_from_spec(spec)
23+
assert spec.loader is not None
24+
try:
25+
spec.loader.exec_module(module)
26+
except RuntimeError:
27+
# In Shiny apps we expect this error:
28+
# RuntimeError: express.ui.page_opts() can only be used inside of a standalone Shiny Express app.
29+
if not app_name.startswith("shiny") or not app_name.endswith("app.py"):
30+
raise
31+
except ModuleNotFoundError as e:
32+
if "shiny" in str(e) and app_name.startswith("shiny"):
33+
pytest.skip("shiny is not installed")
34+
if "dash" in str(e) and app_name.startswith("dash"):
35+
pytest.skip("dash is not installed")
36+
raise
37+
38+
# shinywidgets sets a call back that prevents other
39+
# tests from running correctly
40+
if ITable._widget_construction_callback is not None:
41+
ITable._widget_construction_callback = None
42+
43+
assert module is not None

0 commit comments

Comments
 (0)