Created
December 2, 2025 14:02
-
-
Save dbp/80a240e10ad526045c716e5af52b23ef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| Test file for Lab 10: Choose-Your-Own-Adventure with AI | |
| Tests for the three main functions students need to implement. | |
| """ | |
| import pytest | |
| from adventure_game import ( | |
| StoryChunk, GameWorld, | |
| message_to_story_chunk, integrate_message, request_next_chunk | |
| ) | |
| class TestMessageToStoryChunk: | |
| """Tests for message_to_story_chunk function.""" | |
| def test_basic_conversion(self): | |
| """Test basic message parsing.""" | |
| message = ["The story begins at a large door...", "I open the door.", "I hide."] | |
| expected = StoryChunk("The story begins at a large door...", ["I open the door.", "I hide."]) | |
| result = message_to_story_chunk(message) | |
| assert result.story == expected.story | |
| assert result.choices == expected.choices | |
| def test_empty_message(self): | |
| """Test handling of empty message.""" | |
| message = [] | |
| result = message_to_story_chunk(message) | |
| assert result.story == "" | |
| assert result.choices == [] | |
| def test_story_only(self): | |
| """Test message with only story text, no choices.""" | |
| message = ["The adventure ends here."] | |
| result = message_to_story_chunk(message) | |
| assert result.story == "The adventure ends here." | |
| assert result.choices == [] | |
| def test_multiple_choices(self): | |
| """Test message with many choices.""" | |
| message = [ | |
| "You stand at a crossroads.", | |
| "Go north", | |
| "Go south", | |
| "Go east", | |
| "Go west", | |
| "Stay here" | |
| ] | |
| result = message_to_story_chunk(message) | |
| assert result.story == "You stand at a crossroads." | |
| assert len(result.choices) == 5 | |
| assert result.choices[0] == "Go north" | |
| assert result.choices[4] == "Stay here" | |
| class TestIntegrateMessage: | |
| """Tests for integrate_message function.""" | |
| def test_basic_integration(self): | |
| """Test integrating a message into an existing world.""" | |
| existing_world = GameWorld( | |
| story=[StoryChunk("The story begins at a large door...", ["I open the door.", "I hide."])], | |
| waiting=True | |
| ) | |
| message = ["The door creaks open, and mist floods in...", "I cover my mouth and rush in.", "I turn and run."] | |
| result = integrate_message(existing_world, message) | |
| # Check that new chunk is at the front | |
| assert len(result.story) == 2 | |
| assert result.story[0].story == "The door creaks open, and mist floods in..." | |
| assert result.story[0].choices == ["I cover my mouth and rush in.", "I turn and run."] | |
| # Check that old chunk is still there | |
| assert result.story[1].story == "The story begins at a large door..." | |
| assert result.story[1].choices == ["I open the door.", "I hide."] | |
| # Check other fields | |
| assert result.waiting == False # Should be set to False | |
| def test_integration_empty_world(self): | |
| """Test integrating into an empty world.""" | |
| empty_world = GameWorld([], True) | |
| message = ["Welcome to the adventure!", "Begin the quest.", "Look around first."] | |
| result = integrate_message(empty_world, message) | |
| assert len(result.story) == 1 | |
| assert result.story[0].story == "Welcome to the adventure!" | |
| assert result.story[0].choices == ["Begin the quest.", "Look around first."] | |
| assert result.waiting == False | |
| class TestRequestNextChunk: | |
| """Tests for request_next_chunk function.""" | |
| def test_basic_choice_request(self): | |
| """Test making a basic choice.""" | |
| world = GameWorld( | |
| story=[StoryChunk("The story begins at a large door...", ["I open the door.", "I hide."])], | |
| waiting=False | |
| ) | |
| updated_world, message = request_next_chunk(world, 0) | |
| # Check that choice chunk was added to front | |
| assert len(updated_world.story) == 2 | |
| assert updated_world.story[0].story == "You chose: I open the door." | |
| assert updated_world.story[0].choices == [] | |
| # Check that original chunk is still there | |
| assert updated_world.story[1].story == "The story begins at a large door..." | |
| # Check other fields | |
| assert updated_world.waiting == True | |
| # Check message | |
| assert message == "I open the door." | |
| def test_second_choice(self): | |
| """Test choosing the second option.""" | |
| world = GameWorld( | |
| story=[StoryChunk("What do you do?", ["Fight", "Flee", "Hide"])], | |
| waiting=False | |
| ) | |
| updated_world, message = request_next_chunk(world, 1) | |
| assert updated_world.story[0].story == "You chose: Flee" | |
| assert message == "Flee" | |
| assert updated_world.waiting == True | |
| def test_invalid_choice_index(self): | |
| """Test handling invalid choice indices.""" | |
| world = GameWorld( | |
| story=[StoryChunk("Choose wisely", ["Option 1", "Option 2"])], | |
| waiting=False | |
| ) | |
| # Test negative index | |
| updated_world, message = request_next_chunk(world, -1) | |
| assert updated_world == world # Should be unchanged | |
| assert message == "" | |
| # Test too high index | |
| updated_world, message = request_next_chunk(world, 5) | |
| assert updated_world == world # Should be unchanged | |
| assert message == "" | |
| def test_empty_world(self): | |
| """Test handling empty world.""" | |
| empty_world = GameWorld([], False) | |
| updated_world, message = request_next_chunk(empty_world, 0) | |
| assert updated_world == empty_world | |
| assert message == "" | |
| class TestIntegration: | |
| """Integration tests combining multiple functions.""" | |
| def test_full_workflow(self): | |
| """Test a complete workflow: message -> integrate -> choice -> request.""" | |
| # Start with empty world | |
| world = GameWorld([], False) | |
| # Integrate initial message | |
| initial_message = ["You enter a dark cave.", "Light a torch.", "Feel your way forward."] | |
| world = integrate_message(world, initial_message) | |
| assert len(world.story) == 1 | |
| assert not world.waiting | |
| # Make a choice | |
| world, choice_message = request_next_chunk(world, 0) | |
| assert len(world.story) == 2 | |
| assert world.waiting | |
| assert choice_message == "Light a torch." | |
| assert world.story[0].story == "You chose: Light a torch." | |
| # Integrate response | |
| response_message = ["The torch illuminates ancient drawings on the walls.", "Examine the drawings.", "Continue deeper."] | |
| world = integrate_message(world, response_message) | |
| assert len(world.story) == 3 | |
| assert not world.waiting | |
| assert world.story[0].story == "The torch illuminates ancient drawings on the walls." | |
| if __name__ == "__main__": | |
| # Run tests | |
| pytest.main([__file__, "-v"]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment