Spaces:
Sleeping
Sleeping
Update tests to use required sex parameter
Browse files- Replace 'Unknown' sex values with 'Male' or 'Female' in test fixtures
- Update test CSV files to include sex column with valid values
- Fix test assertions to account for new UI component visibility behavior
- Adjust expected output structure to include settings_input in yields
- tests/test_gradio_app.py +6 -6
- tests/test_ui_events.py +49 -11
tests/test_gradio_app.py
CHANGED
|
@@ -81,9 +81,9 @@ class TestLoadSettings:
|
|
| 81 |
def temp_settings_csv(self):
|
| 82 |
"""Create a temporary settings CSV file with all columns."""
|
| 83 |
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".csv") as f:
|
| 84 |
-
f.write("Slide,Site Type,Cancer Subtype,IHC Subtype,Segmentation Config\n")
|
| 85 |
-
f.write("slide1.svs,Primary,Unknown,,Biopsy\n")
|
| 86 |
-
f.write("slide2.svs,Metastatic,Unknown,,Resection\n")
|
| 87 |
temp_path = f.name
|
| 88 |
yield temp_path
|
| 89 |
Path(temp_path).unlink()
|
|
@@ -92,9 +92,9 @@ class TestLoadSettings:
|
|
| 92 |
def temp_minimal_settings_csv(self):
|
| 93 |
"""Create a temporary settings CSV file with minimal columns."""
|
| 94 |
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".csv") as f:
|
| 95 |
-
f.write("Slide,Site Type\n")
|
| 96 |
-
f.write("slide1.svs,Primary\n")
|
| 97 |
-
f.write("slide2.svs,Metastatic\n")
|
| 98 |
temp_path = f.name
|
| 99 |
yield temp_path
|
| 100 |
Path(temp_path).unlink()
|
|
|
|
| 81 |
def temp_settings_csv(self):
|
| 82 |
"""Create a temporary settings CSV file with all columns."""
|
| 83 |
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".csv") as f:
|
| 84 |
+
f.write("Slide,Site Type,Sex,Cancer Subtype,IHC Subtype,Segmentation Config\n")
|
| 85 |
+
f.write("slide1.svs,Primary,Male,Unknown,,Biopsy\n")
|
| 86 |
+
f.write("slide2.svs,Metastatic,Female,Unknown,,Resection\n")
|
| 87 |
temp_path = f.name
|
| 88 |
yield temp_path
|
| 89 |
Path(temp_path).unlink()
|
|
|
|
| 92 |
def temp_minimal_settings_csv(self):
|
| 93 |
"""Create a temporary settings CSV file with minimal columns."""
|
| 94 |
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".csv") as f:
|
| 95 |
+
f.write("Slide,Site Type,Sex\n")
|
| 96 |
+
f.write("slide1.svs,Primary,Male\n")
|
| 97 |
+
f.write("slide2.svs,Metastatic,Female\n")
|
| 98 |
temp_path = f.name
|
| 99 |
yield temp_path
|
| 100 |
Path(temp_path).unlink()
|
tests/test_ui_events.py
CHANGED
|
@@ -69,7 +69,7 @@ class TestGeneratorBehavior:
|
|
| 69 |
{
|
| 70 |
"Slide": ["test_slide_1.svs"],
|
| 71 |
"Site Type": ["Primary"],
|
| 72 |
-
"Sex": ["
|
| 73 |
"Tissue Site": ["Unknown"],
|
| 74 |
"Cancer Subtype": ["Unknown"],
|
| 75 |
"IHC Subtype": [""],
|
|
@@ -138,7 +138,7 @@ class TestGeneratorBehavior:
|
|
| 138 |
{
|
| 139 |
"Slide": ["test_slide_1.svs", "test_slide_2.svs", "test_slide_3.svs"],
|
| 140 |
"Site Type": ["Primary", "Primary", "Primary"],
|
| 141 |
-
"Sex": ["
|
| 142 |
"Tissue Site": ["Unknown", "Unknown", "Unknown"],
|
| 143 |
"Cancer Subtype": ["Unknown", "Unknown", "Unknown"],
|
| 144 |
"IHC Subtype": ["", "", ""],
|
|
@@ -161,13 +161,37 @@ class TestGeneratorBehavior:
|
|
| 161 |
# Get first intermediate yield (after first slide)
|
| 162 |
first_yield = next(gen)
|
| 163 |
|
| 164 |
-
# Should be tuple with
|
| 165 |
-
assert len(first_yield) ==
|
| 166 |
|
| 167 |
-
# First element is
|
| 168 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
assert len(slide_masks) == 1
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
@patch("mosaic.ui.app.load_all_models")
|
| 172 |
@patch("mosaic.ui.app.analyze_slide")
|
| 173 |
@patch("mosaic.ui.app.create_user_directory")
|
|
@@ -214,7 +238,7 @@ class TestGeneratorBehavior:
|
|
| 214 |
{
|
| 215 |
"Slide": ["test_slide_1.svs", "test_slide_2.svs", "test_slide_3.svs"],
|
| 216 |
"Site Type": ["Primary", "Primary", "Primary"],
|
| 217 |
-
"Sex": ["
|
| 218 |
"Tissue Site": ["Unknown", "Unknown", "Unknown"],
|
| 219 |
"Cancer Subtype": ["Unknown", "Unknown", "Unknown"],
|
| 220 |
"IHC Subtype": ["", "", ""],
|
|
@@ -238,11 +262,25 @@ class TestGeneratorBehavior:
|
|
| 238 |
results = list(gen)
|
| 239 |
final_yield = results[-1]
|
| 240 |
|
| 241 |
-
# Final yield should have all results
|
| 242 |
-
assert len(final_yield) ==
|
| 243 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 244 |
assert len(slide_masks) == 3 # All 3 slides
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
|
| 247 |
class TestErrorDisplay:
|
| 248 |
"""Test error and warning display behavior."""
|
|
@@ -307,7 +345,7 @@ class TestErrorDisplay:
|
|
| 307 |
# Verify defaults applied
|
| 308 |
assert result.iloc[0]["Site Type"] == "Primary" # Invalid → Primary
|
| 309 |
assert result.iloc[0]["Cancer Subtype"] == "Unknown" # Invalid → Unknown
|
| 310 |
-
assert result.iloc[1]["Sex"] == "
|
| 311 |
assert result.iloc[1]["Segmentation Config"] == "Biopsy" # Invalid → Biopsy
|
| 312 |
|
| 313 |
@patch("mosaic.ui.app.create_user_directory")
|
|
|
|
| 69 |
{
|
| 70 |
"Slide": ["test_slide_1.svs"],
|
| 71 |
"Site Type": ["Primary"],
|
| 72 |
+
"Sex": ["Male"],
|
| 73 |
"Tissue Site": ["Unknown"],
|
| 74 |
"Cancer Subtype": ["Unknown"],
|
| 75 |
"IHC Subtype": [""],
|
|
|
|
| 138 |
{
|
| 139 |
"Slide": ["test_slide_1.svs", "test_slide_2.svs", "test_slide_3.svs"],
|
| 140 |
"Site Type": ["Primary", "Primary", "Primary"],
|
| 141 |
+
"Sex": ["Male", "Female", "Male"],
|
| 142 |
"Tissue Site": ["Unknown", "Unknown", "Unknown"],
|
| 143 |
"Cancer Subtype": ["Unknown", "Unknown", "Unknown"],
|
| 144 |
"IHC Subtype": ["", "", ""],
|
|
|
|
| 161 |
# Get first intermediate yield (after first slide)
|
| 162 |
first_yield = next(gen)
|
| 163 |
|
| 164 |
+
# Should be tuple with 7 elements (added settings_input back)
|
| 165 |
+
assert len(first_yield) == 7
|
| 166 |
|
| 167 |
+
# First element is settings_input (visible during processing for progress)
|
| 168 |
+
settings = first_yield[0]
|
| 169 |
+
assert hasattr(settings, "visible") and settings.visible
|
| 170 |
+
|
| 171 |
+
# Second element is slide_masks (should have 1 entry)
|
| 172 |
+
slide_masks = first_yield[1]
|
| 173 |
assert len(slide_masks) == 1
|
| 174 |
|
| 175 |
+
# Third element should be AEON results DataFrame (now visible with partial results)
|
| 176 |
+
aeon_output = first_yield[2]
|
| 177 |
+
# Should have a DataFrame (not hidden anymore)
|
| 178 |
+
assert aeon_output is not None
|
| 179 |
+
|
| 180 |
+
# Fourth element should be AEON download button (hidden until complete)
|
| 181 |
+
aeon_download = first_yield[3]
|
| 182 |
+
# Download button should be hidden during intermediate yields
|
| 183 |
+
assert hasattr(aeon_download, "visible") and not aeon_download.visible
|
| 184 |
+
|
| 185 |
+
# Fifth element should be PALADIN results DataFrame (partial results)
|
| 186 |
+
paladin_output = first_yield[4]
|
| 187 |
+
# Should have data (DataFrame with partial results)
|
| 188 |
+
assert paladin_output is not None
|
| 189 |
+
|
| 190 |
+
# Sixth element should be PALADIN download button (hidden until complete)
|
| 191 |
+
paladin_download = first_yield[5]
|
| 192 |
+
# Download button should be hidden during intermediate yields
|
| 193 |
+
assert hasattr(paladin_download, "visible") and not paladin_download.visible
|
| 194 |
+
|
| 195 |
@patch("mosaic.ui.app.load_all_models")
|
| 196 |
@patch("mosaic.ui.app.analyze_slide")
|
| 197 |
@patch("mosaic.ui.app.create_user_directory")
|
|
|
|
| 238 |
{
|
| 239 |
"Slide": ["test_slide_1.svs", "test_slide_2.svs", "test_slide_3.svs"],
|
| 240 |
"Site Type": ["Primary", "Primary", "Primary"],
|
| 241 |
+
"Sex": ["Male", "Female", "Male"],
|
| 242 |
"Tissue Site": ["Unknown", "Unknown", "Unknown"],
|
| 243 |
"Cancer Subtype": ["Unknown", "Unknown", "Unknown"],
|
| 244 |
"IHC Subtype": ["", "", ""],
|
|
|
|
| 262 |
results = list(gen)
|
| 263 |
final_yield = results[-1]
|
| 264 |
|
| 265 |
+
# Final yield should have all results (7 elements with settings_input)
|
| 266 |
+
assert len(final_yield) == 7
|
| 267 |
+
|
| 268 |
+
# First element is settings_input (should be visible for 3 slides)
|
| 269 |
+
settings = final_yield[0]
|
| 270 |
+
assert hasattr(settings, "visible") and settings.visible # Visible for multiple slides
|
| 271 |
+
|
| 272 |
+
# Second element is slide_masks
|
| 273 |
+
slide_masks = final_yield[1]
|
| 274 |
assert len(slide_masks) == 3 # All 3 slides
|
| 275 |
|
| 276 |
+
# AEON download button should be visible on final yield (4th element, index 3)
|
| 277 |
+
aeon_download = final_yield[3]
|
| 278 |
+
assert hasattr(aeon_download, "visible") and aeon_download.visible
|
| 279 |
+
|
| 280 |
+
# PALADIN download button should be visible on final yield (6th element, index 5)
|
| 281 |
+
paladin_download = final_yield[5]
|
| 282 |
+
assert hasattr(paladin_download, "visible") and paladin_download.visible
|
| 283 |
+
|
| 284 |
|
| 285 |
class TestErrorDisplay:
|
| 286 |
"""Test error and warning display behavior."""
|
|
|
|
| 345 |
# Verify defaults applied
|
| 346 |
assert result.iloc[0]["Site Type"] == "Primary" # Invalid → Primary
|
| 347 |
assert result.iloc[0]["Cancer Subtype"] == "Unknown" # Invalid → Unknown
|
| 348 |
+
assert result.iloc[1]["Sex"] == "" # Invalid → empty string
|
| 349 |
assert result.iloc[1]["Segmentation Config"] == "Biopsy" # Invalid → Biopsy
|
| 350 |
|
| 351 |
@patch("mosaic.ui.app.create_user_directory")
|