Skip to content

Commit 2bd6bad

Browse files
committed
Improved app testing
1 parent 5443b2f commit 2bd6bad

File tree

2 files changed

+60
-21
lines changed

2 files changed

+60
-21
lines changed

src/tdamapper/app.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from sklearn.preprocessing import StandardScaler
1111
from umap import UMAP
1212

13-
from tdamapper.clustering import TrivialClustering
13+
from tdamapper.core import TrivialClustering
1414
from tdamapper.cover import BallCover, CubicalCover, KNNCover
1515
from tdamapper.learn import MapperAlgorithm
1616
from tdamapper.plot import MapperPlot
@@ -636,17 +636,17 @@ def load_file(self):
636636
self.storage["df"] = fix_data(df)
637637
self.storage["labels"] = fix_data(labels)
638638
elif self.load_type.value == LOAD_CSV:
639-
df = self.storage.get("df")
640-
if df is None:
639+
df = self.storage.get("df", pd.DataFrame())
640+
if df is None or df.empty:
641641
logger.warning("No data found. Please upload a file first.")
642642
ui.notify("No data found. Please upload a file first.", type="warning")
643643
return
644644
else:
645645
logger.error("Unknown load type selected.")
646646
return
647647

648-
df = self.storage.get("df")
649-
if df is not None:
648+
df = self.storage.get("df", pd.DataFrame())
649+
if df is not None or not df.empty:
650650
logger.info("Data loaded successfully.")
651651
ui.notify("File loaded successfully.", type="positive")
652652
else:
@@ -657,18 +657,27 @@ async def async_run_mapper(self):
657657
notification = ui.notification(timeout=None, type="ongoing")
658658
notification.message = "Running Mapper..."
659659
notification.spinner = True
660-
df_X = self.storage.get("df")
660+
df_X = self.storage.get("df", pd.DataFrame())
661661
if df_X is None or df_X.empty:
662662
logger.warning("No data found. Please upload a file first.")
663663
ui.notify("No data found. Please upload a file first.", type="warning")
664+
notification.message = "No data found. Please upload a file first."
665+
notification.spinner = False
666+
notification.dismiss()
664667
return
665668
mapper_config = self.get_mapper_config()
666-
mapper_graph, df_y = await run.cpu_bound(
667-
run_mapper, df_X, **asdict(mapper_config)
668-
)
669-
self.storage["mapper_graph"] = mapper_graph
670-
self.storage["df_y"] = df_y
671-
notification.message = "Done!"
669+
result = await run.cpu_bound(run_mapper, df_X, **asdict(mapper_config))
670+
if result is None:
671+
notification.message = "Something went wrong."
672+
notification.spinner = False
673+
notification.dismiss()
674+
return
675+
mapper_graph, df_y = result
676+
if mapper_graph is not None:
677+
self.storage["mapper_graph"] = mapper_graph
678+
if df_y is not None:
679+
self.storage["df_y"] = df_y
680+
notification.message = "Running Mapper Completed!"
672681
notification.spinner = False
673682
notification.dismiss()
674683

@@ -713,23 +722,25 @@ async def async_draw_mapper(self):
713722
with self.plot_container:
714723
self.draw_area = ui.plotly(mapper_fig).classes("w-full h-full")
715724

716-
notification.message = "Done!"
725+
notification.message = "Drawing Mapper Completed!"
717726
notification.spinner = False
718727
notification.dismiss()
719728

720729

721-
@ui.page("/")
722-
def main_page():
723-
ui.query(".nicegui-content").classes("p-0")
724-
storage = app.storage.client
725-
App(storage=storage)
730+
def startup():
731+
@ui.page("/")
732+
def main_page():
733+
ui.query(".nicegui-content").classes("p-0")
734+
storage = app.storage.client
735+
App(storage=storage)
726736

727737

728738
def main():
729739
port = os.getenv("PORT", "8080")
730740
host = os.getenv("HOST", "0.0.0.0")
731741
production = os.getenv("PRODUCTION", "false").lower() == "true"
732742
storage_secret = os.getenv("STORAGE_SECRET", "storage_secret")
743+
startup()
733744
ui.run(
734745
storage_secret=storage_secret,
735746
reload=not production,

tests/test_unit_app.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
1-
import pytest
1+
from dataclasses import asdict
2+
23
from nicegui.testing import User
4+
from sklearn.datasets import load_digits
35

46
from tdamapper import app
57

68
pytest_plugins = ["nicegui.testing.user_plugin"]
79

810

9-
@pytest.mark.module_under_test(app)
10-
async def test_run_mapper(user: User) -> None:
11+
async def test_run_app(user: User) -> None:
12+
app.startup()
1113
await user.open("/")
1214
await user.should_see("Load Data")
15+
await user.should_see("Lens")
16+
await user.should_see("Cover")
17+
await user.should_see("Clustering")
1318
await user.should_see("Run Mapper")
19+
await user.should_see("Redraw")
1420
user.find("Load Data").click()
1521
await user.should_see("File loaded successfully")
22+
await user.should_not_see("No data found.")
1623
user.find("Run Mapper").click()
1724
await user.should_see("Running Mapper...")
25+
await user.should_not_see("No data found.")
26+
await user.should_see("Running Mapper Completed!", retries=20)
27+
await user.should_see("Drawing Mapper...")
28+
await user.should_not_see("No data")
29+
await user.should_see("Drawing Mapper Completed!", retries=20)
30+
user.find("Redraw").click()
31+
await user.should_see("Drawing Mapper...")
32+
await user.should_not_see("No data")
33+
await user.should_see("Drawing Mapper Completed!", retries=20)
34+
35+
36+
def test_run_mapper() -> None:
37+
config = app.MapperConfig()
38+
df_X, df_target = load_digits(return_X_y=True, as_frame=True)
39+
result = app.run_mapper(df_X, **asdict(config))
40+
assert result is not None
41+
mapper_graph, df_y = result
42+
mapper_fig = app.create_mapper_figure(
43+
df_X, df_y, df_target, mapper_graph, **asdict(config)
44+
)
45+
assert mapper_fig is not None

0 commit comments

Comments
 (0)