Download tests/unit/test_simulator.py from AIVLAD/demo: direct link, hf CLI and curl.
- Browser
- Download file 7.61 kB
-
https://huggingface.co/spaces/AIVLAD/demo/resolve/main/tests/unit/test_simulator.py
- Command line
-
hf download hf://spaces/AIVLAD/demo/tests/unit/test_simulator.py
-
curl -L -o test_simulator.py https://huggingface.co/spaces/AIVLAD/demo/resolve/main/tests/unit/test_simulator.py
7.61 kB
| """Unit tests for wall construction simulator.""" | |
| from __future__ import annotations | |
| from datetime import date | |
| from decimal import Decimal | |
| from pathlib import Path | |
| import pytest | |
| from apps.profiles.models import DailyProgress, Profile, WallSection | |
| from apps.profiles.services.simulator import ProfileConfig, SectionData, WallSimulator | |
| class TestWallSimulator: | |
| """Test cases for WallSimulator.""" | |
| def test_initialize_single_profile(self, tmp_path: Path) -> None: | |
| """Test initializing simulator with single profile.""" | |
| profiles_config = [ProfileConfig(heights=[21, 25, 28])] | |
| simulator = WallSimulator(num_teams=2, log_dir=str(tmp_path)) | |
| section_data = simulator._initialize_profiles(profiles_config) | |
| assert len(section_data) == 3 | |
| assert Profile.objects.count() == 1 | |
| assert WallSection.objects.count() == 3 | |
| profile = Profile.objects.first() | |
| assert profile is not None | |
| assert profile.name == "Profile 1" | |
| def test_initialize_multiple_profiles(self, tmp_path: Path) -> None: | |
| """Test initializing simulator with multiple profiles.""" | |
| profiles_config = [ | |
| ProfileConfig(heights=[21, 25, 28]), | |
| ProfileConfig(heights=[17]), | |
| ProfileConfig(heights=[17, 22, 17, 19, 17]), | |
| ] | |
| simulator = WallSimulator(num_teams=4, log_dir=str(tmp_path)) | |
| section_data = simulator._initialize_profiles(profiles_config) | |
| assert len(section_data) == 9 | |
| assert Profile.objects.count() == 3 | |
| assert WallSection.objects.count() == 9 | |
| def test_assign_work_limits_by_teams(self, tmp_path: Path) -> None: | |
| """Test that work assignment respects team limit.""" | |
| section_data = [ | |
| SectionData( | |
| id=i, | |
| profile_id=1, | |
| profile_name="Profile 1", | |
| section_name=f"Section {i}", | |
| current_height=20, | |
| ) | |
| for i in range(10) | |
| ] | |
| simulator = WallSimulator(num_teams=3, log_dir=str(tmp_path)) | |
| assigned = simulator._assign_work(section_data) | |
| assert len(assigned) == 3 | |
| def test_assign_work_skips_completed_sections(self, tmp_path: Path) -> None: | |
| """Test that completed sections are not assigned.""" | |
| section_data = [ | |
| SectionData(id=1, profile_id=1, profile_name="Profile 1", section_name="Section 1", current_height=30), | |
| SectionData(id=2, profile_id=1, profile_name="Profile 1", section_name="Section 2", current_height=25), | |
| SectionData(id=3, profile_id=1, profile_name="Profile 1", section_name="Section 3", current_height=30), | |
| SectionData(id=4, profile_id=1, profile_name="Profile 1", section_name="Section 4", current_height=28), | |
| ] | |
| simulator = WallSimulator(num_teams=5, log_dir=str(tmp_path)) | |
| assigned = simulator._assign_work(section_data) | |
| assert len(assigned) == 2 | |
| assert all(s.current_height < 30 for s in assigned) | |
| def test_process_section_calculates_correctly(self, tmp_path: Path) -> None: | |
| """Test that section processing calculates ice and cost correctly.""" | |
| section = SectionData( | |
| id=1, | |
| profile_id=1, | |
| profile_name="Profile 1", | |
| section_name="Section 1", | |
| current_height=20, | |
| ) | |
| simulator = WallSimulator(num_teams=1, log_dir=str(tmp_path)) | |
| result = simulator._process_section(section, day=1, team_id=0) | |
| assert result.section_id == 1 | |
| assert result.feet_built == Decimal("1") | |
| assert result.ice == Decimal("195") | |
| assert result.cost == Decimal("370500") | |
| def test_process_section_writes_log(self, tmp_path: Path) -> None: | |
| """Test that section processing writes to log file.""" | |
| section = SectionData( | |
| id=1, | |
| profile_id=1, | |
| profile_name="Profile 1", | |
| section_name="Section 1", | |
| current_height=20, | |
| ) | |
| simulator = WallSimulator(num_teams=1, log_dir=str(tmp_path)) | |
| simulator._process_section(section, day=1, team_id=0) | |
| log_file = tmp_path / "team_0.log" | |
| assert log_file.exists() | |
| log_content = log_file.read_text() | |
| assert "Day 1" in log_content | |
| assert "Section 1" in log_content | |
| def test_process_section_logs_completion(self, tmp_path: Path) -> None: | |
| """Test that section completion is logged.""" | |
| section = SectionData( | |
| id=1, | |
| profile_id=1, | |
| profile_name="Profile 1", | |
| section_name="Section 1", | |
| current_height=29, | |
| ) | |
| simulator = WallSimulator(num_teams=1, log_dir=str(tmp_path)) | |
| simulator._process_section(section, day=1, team_id=0) | |
| log_file = tmp_path / "team_0.log" | |
| log_content = log_file.read_text() | |
| assert "completed" in log_content | |
| def test_simulate_simple_profile(self, tmp_path: Path) -> None: | |
| """Test complete simulation with simple profile.""" | |
| profiles_config = [ProfileConfig(heights=[28, 29])] | |
| simulator = WallSimulator(num_teams=2, log_dir=str(tmp_path)) | |
| result = simulator.simulate(profiles_config, date(2025, 10, 20)) | |
| assert result.total_days == 2 | |
| assert result.total_sections == 2 | |
| # 3 DailyProgress records: Day 1 both sections (28→29, 29→30), Day 2 first section only (29→30) | |
| assert DailyProgress.objects.count() == 3 | |
| profile = Profile.objects.first() | |
| assert profile is not None | |
| sections = WallSection.objects.filter(profile=profile) | |
| for section in sections: | |
| assert section.current_height == 30 | |
| def test_simulate_creates_logs(self, tmp_path: Path) -> None: | |
| """Test that simulation creates team log files.""" | |
| profiles_config = [ProfileConfig(heights=[28])] | |
| simulator = WallSimulator(num_teams=2, log_dir=str(tmp_path)) | |
| simulator.simulate(profiles_config, date(2025, 10, 20)) | |
| assert (tmp_path / "team_0.log").exists() | |
| assert (tmp_path / "team_1.log").exists() | |
| log_content = (tmp_path / "team_0.log").read_text() | |
| assert "relieved" in log_content | |
| def test_simulate_respects_team_limit(self, tmp_path: Path) -> None: | |
| """Test that simulation respects team limit.""" | |
| profiles_config = [ProfileConfig(heights=[25, 25, 25, 25, 25])] | |
| simulator = WallSimulator(num_teams=2, log_dir=str(tmp_path)) | |
| simulator.simulate(profiles_config, date(2025, 10, 20)) | |
| progress_by_day: dict[str, int] = {} | |
| for progress in DailyProgress.objects.all(): | |
| day_key = progress.date.isoformat() | |
| progress_by_day[day_key] = progress_by_day.get(day_key, 0) + 1 | |
| for count in progress_by_day.values(): | |
| assert count <= 2 | |
| def test_simulate_with_varying_heights(self, tmp_path: Path) -> None: | |
| """Test simulation with varying initial heights.""" | |
| profiles_config = [ProfileConfig(heights=[21, 25, 28, 30, 17])] | |
| simulator = WallSimulator(num_teams=3, log_dir=str(tmp_path)) | |
| result = simulator.simulate(profiles_config, date(2025, 10, 20)) | |
| assert result.total_sections == 5 | |
| sections_with_height_30 = WallSection.objects.filter(initial_height=30, current_height=30).count() | |
| assert sections_with_height_30 == 1 | |
| all_sections = WallSection.objects.all() | |
| for section in all_sections: | |
| assert section.current_height == 30 | |