import pytest import json from flowtimer.Schedule import Schedule from flowtimer.Phase import Phase from flowtimer.RecurringPhaseSequence import RecurringPhaseSequence class TestSchedule: @pytest.fixture def setup_schedule(self): # Set up some real Phase and RecurringPhaseSequence objects for testing phase1 = Phase("Phase 1", 300) phase2 = Phase("Phase 2", 600) sequence = RecurringPhaseSequence("Sequence 1", [phase1, phase2], 2) blocks = [phase1, sequence] schedule = Schedule("Test Schedule", blocks) return schedule, phase1, phase2, sequence def test_initialization(self, setup_schedule): schedule, phase1, _, _ = setup_schedule assert schedule.title == "Test Schedule" assert schedule.blocks == [phase1, schedule.blocks[1]] assert schedule.current_block == phase1 assert schedule.state == "initial" def test_default_json_string(self): default_json = Schedule.default_json_string() assert isinstance(default_json, str) def test_from_json(self): json_string = Schedule.default_json_string() schedule = Schedule.from_json(json_string) assert schedule.title == "Default" assert len(schedule.blocks) == 2 assert isinstance(schedule.blocks[0], Phase) assert isinstance(schedule.blocks[1], RecurringPhaseSequence) def test_to_json(self, setup_schedule): schedule, _, _, _ = setup_schedule json_string = schedule.to_json() assert isinstance(json_string, str) data = json.loads(json_string) assert data['title'] == "Test Schedule" assert len(data['blocks']) == 2 def test_start(self, setup_schedule): schedule, phase1, _, _ = setup_schedule schedule.start() assert schedule.state == "running" # assert phase1.ticks_left < phase1.initial_ticks # Assuming the phase reduces ticks when started def test_running(self, setup_schedule): schedule, _, _, _ = setup_schedule schedule.start() assert schedule.running() is True schedule.pause() assert schedule.running() is False def test_paused(self, setup_schedule): schedule, _, _, _ = setup_schedule schedule.pause() assert schedule.paused() is True def test_abort(self, setup_schedule): schedule, _, _, _ = setup_schedule schedule.abort() assert schedule.state == "aborted" def test_completed(self, setup_schedule): schedule, phase1, _, sequence = setup_schedule schedule.tick(phase1.initial_ticks) # Complete phase1 schedule.tick(sequence.initial_ticks) # Complete sequence schedule.tick(phase1.initial_ticks) # Complete phase1 schedule.tick(sequence.initial_ticks) # Complete sequence print(schedule.current_block) assert schedule.completed() is True assert schedule.state == "completed" def test_advance_to_next_block(self, setup_schedule): schedule, _, _, sequence = setup_schedule schedule.advance_to_next_block() assert schedule.current_block == schedule.blocks[1] def test_skip(self, setup_schedule): schedule, _, _, sequence = setup_schedule schedule.skip() assert schedule.current_block == schedule.blocks[1] # Should skip to Phase 2 within the sequence def test_total_ticks_left(self, setup_schedule): schedule, phase1, phase2, sequence = setup_schedule expected_total_ticks = phase1.ticks_left + sequence.ticks_left assert schedule.total_ticks_left() == expected_total_ticks def test_upcoming_blocks(self, setup_schedule): schedule, _, _, sequence = setup_schedule assert schedule.upcoming_blocks() == [sequence] def test_current_block_is_final(self, setup_schedule): schedule, _, _, sequence = setup_schedule assert schedule.current_block_is_final() is False schedule.advance_to_next_block() assert schedule.current_block_is_final() is True def test_tick(self, setup_schedule): schedule, phase1, _, _ = setup_schedule initial_ticks = phase1.ticks_left schedule.tick(100) assert phase1.ticks_left == initial_ticks - 100 schedule.tick(phase1.ticks_left) # Finish phase1 assert schedule.current_block == schedule.blocks[1] # Should advance to the next block