Download tests/test_difficulty_analyzer.py from InternsProgressUpdate/Venket: direct link, hf CLI and curl.
- Browser
- Download file 4.2 kB
-
https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/tests/test_difficulty_analyzer.py
- Command line
-
hf download hf://InternsProgressUpdate/Venket/tests/test_difficulty_analyzer.py
-
curl -L -o test_difficulty_analyzer.py https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/tests/test_difficulty_analyzer.py
4.2 kB
| """Unit tests for src.analysis.difficulty_analyzer -- verifies the exact spec formula.""" | |
| from __future__ import annotations | |
| import math | |
| from src.analysis.difficulty_analyzer import DifficultyAnalyzer | |
| from src.analysis.geometry_analyzer import GeometryResult | |
| from src.config.schema import DifficultyWeights | |
| def _geometry( | |
| polygon_overlap_proxy: float, whitespace_ratio: float, mean_dark_intensity: float, | |
| signature_area_ratio: float, gray_stddev: float, | |
| ) -> GeometryResult: | |
| box = (0.0, 0.0, 100.0, 20.0) | |
| return GeometryResult( | |
| found=True, signature_bbox_px=box, min_rotated_rect={}, signature_polygon_px=[[0, 0], [1, 0], [1, 1]], | |
| convex_hull_px=[], centroid_px=(50.0, 10.0), orientation_deg=0.0, ink_pixels=100, | |
| target_box=box, actual_box=box, search_box=box, | |
| box_coverage_pct=0.0, containment_pct=0.0, ink_fill_ratio=1 - whitespace_ratio, | |
| polygon_overlap_proxy=polygon_overlap_proxy, distance_from_box_center_px=0.0, margin_utilization=0.0, | |
| mean_dark_intensity=mean_dark_intensity, gray_stddev=gray_stddev, | |
| signature_area_ratio=signature_area_ratio, whitespace_ratio=whitespace_ratio, | |
| ) | |
| def test_difficulty_score_matches_exact_spec_formula(): | |
| weights = DifficultyWeights() | |
| analyzer = DifficultyAnalyzer(weights) | |
| geom = _geometry( | |
| polygon_overlap_proxy=0.4, # misplacement = 0.6 | |
| whitespace_ratio=0.5, # whitespace = 0.5 | |
| mean_dark_intensity=150.0, # faintness = clamp((150-90)/120) = 0.5 | |
| signature_area_ratio=0.02, # smallness = clamp(1 - 0.02/0.04) = 0.5 | |
| gray_stddev=30.0, # low_texture = clamp(1 - 30/60) = 0.5 | |
| ) | |
| result = analyzer.analyze(geom) | |
| assert math.isclose(result.misplacement, 0.6, abs_tol=1e-6) | |
| assert math.isclose(result.whitespace, 0.5, abs_tol=1e-6) | |
| assert math.isclose(result.faintness, 0.5, abs_tol=1e-6) | |
| assert math.isclose(result.smallness, 0.5, abs_tol=1e-6) | |
| assert math.isclose(result.low_texture, 0.5, abs_tol=1e-6) | |
| expected = 0.35 * 0.6 + 0.20 * 0.5 + 0.20 * 0.5 + 0.15 * 0.5 + 0.10 * 0.5 | |
| assert math.isclose(result.score, expected, abs_tol=1e-6) | |
| def test_difficulty_components_are_clamped_to_unit_interval(): | |
| weights = DifficultyWeights() | |
| analyzer = DifficultyAnalyzer(weights) | |
| geom = _geometry( | |
| polygon_overlap_proxy=-5.0, # misplacement would exceed 1 -> clamp to 1 | |
| whitespace_ratio=2.0, # clamp to 1 | |
| mean_dark_intensity=1000.0, # faintness clamp to 1 | |
| signature_area_ratio=-1.0, # smallness clamp to 1 | |
| gray_stddev=-10.0, # low_texture clamp to 1 | |
| ) | |
| result = analyzer.analyze(geom) | |
| assert result.misplacement == 1.0 | |
| assert result.whitespace == 1.0 | |
| assert result.faintness == 1.0 | |
| assert result.smallness == 1.0 | |
| assert result.low_texture == 1.0 | |
| assert result.score == 1.0 | |
| assert result.tier == "hard" | |
| def test_difficulty_tier_boundaries(): | |
| weights = DifficultyWeights() | |
| analyzer = DifficultyAnalyzer(weights) | |
| # All-zero components -> score 0 -> easy. | |
| geom_easy = _geometry( | |
| polygon_overlap_proxy=1.0, whitespace_ratio=0.0, mean_dark_intensity=90.0, | |
| signature_area_ratio=0.04, gray_stddev=60.0, | |
| ) | |
| assert analyzer.analyze(geom_easy).tier == "easy" | |
| assert analyzer.analyze(geom_easy).score == 0.0 | |
| # All components at 1.0 -> score 1.0 -> hard. | |
| geom_hard = _geometry( | |
| polygon_overlap_proxy=0.0, whitespace_ratio=1.0, mean_dark_intensity=300.0, | |
| signature_area_ratio=0.0, gray_stddev=0.0, | |
| ) | |
| assert analyzer.analyze(geom_hard).tier == "hard" | |
| def test_difficulty_score_is_reproducible_given_same_geometry(): | |
| weights = DifficultyWeights() | |
| analyzer = DifficultyAnalyzer(weights) | |
| geom = _geometry(0.3, 0.4, 140.0, 0.01, 25.0) | |
| r1 = analyzer.analyze(geom) | |
| r2 = analyzer.analyze(geom) | |
| assert r1 == r2 | |
| def test_difficulty_weights_must_sum_to_one(): | |
| import pytest | |
| from pydantic import ValidationError | |
| with pytest.raises(ValidationError): | |
| DifficultyWeights(misplacement=0.9, whitespace=0.2, faintness=0.2, smallness=0.15, low_texture=0.10) | |