| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | # Tests for Generate.py (ArchipelagoGenerate.exe) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2023-10-02 08:47:28 +02:00
										 |  |  | import os | 
					
						
							|  |  |  | import os.path | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2023-10-02 08:47:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | from pathlib import Path | 
					
						
							|  |  |  | from tempfile import TemporaryDirectory | 
					
						
							| 
									
										
										
										
											2023-10-02 08:47:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | import Generate | 
					
						
							| 
									
										
										
										
											2024-06-16 03:27:06 +02:00
										 |  |  | import Main | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestGenerateMain(unittest.TestCase): | 
					
						
							|  |  |  |     """This tests Generate.py (ArchipelagoGenerate.exe) main""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     generate_dir = Path(Generate.__file__).parent | 
					
						
							| 
									
										
										
										
											2022-12-11 13:15:23 +01:00
										 |  |  |     run_dir = generate_dir / "test"  # reproducible cwd that's neither __file__ nor Generate.__file__ | 
					
						
							| 
									
										
										
										
											2023-10-22 06:00:27 -05:00
										 |  |  |     abs_input_dir = Path(__file__).parent / 'data' / 'one_player' | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  |     rel_input_dir = abs_input_dir.relative_to(run_dir)  # directly supplied relative paths are relative to cwd | 
					
						
							|  |  |  |     yaml_input_dir = abs_input_dir.relative_to(generate_dir)  # yaml paths are relative to user_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def assertOutput(self, output_dir: str): | 
					
						
							|  |  |  |         output_path = Path(output_dir) | 
					
						
							|  |  |  |         output_files = list(output_path.glob('*.zip')) | 
					
						
							|  |  |  |         if len(output_files) == 1: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         self.fail(f"Expected {output_dir} to contain one zip, but has {len(output_files)}: " | 
					
						
							|  |  |  |                   f"{list(output_path.glob('*'))}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2022-12-11 13:15:23 +01:00
										 |  |  |         self.original_argv = sys.argv.copy() | 
					
						
							|  |  |  |         self.original_cwd = os.getcwd() | 
					
						
							|  |  |  |         self.original_local_path = Generate.Utils.local_path.cached_path | 
					
						
							|  |  |  |         self.original_user_path = Generate.Utils.user_path.cached_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Force both user_path and local_path to a specific path. They have independent caches. | 
					
						
							|  |  |  |         Generate.Utils.user_path.cached_path = Generate.Utils.local_path.cached_path = str(self.generate_dir) | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  |         os.chdir(self.run_dir) | 
					
						
							|  |  |  |         self.output_tempdir = TemporaryDirectory(prefix='AP_out_') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-24 12:08:19 +02:00
										 |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         self.output_tempdir.cleanup() | 
					
						
							| 
									
										
										
										
											2022-12-11 13:15:23 +01:00
										 |  |  |         os.chdir(self.original_cwd) | 
					
						
							|  |  |  |         sys.argv = self.original_argv | 
					
						
							|  |  |  |         Generate.Utils.local_path.cached_path = self.original_local_path | 
					
						
							|  |  |  |         Generate.Utils.user_path.cached_path = self.original_user_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_paths(self): | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(self.generate_dir)) | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(self.run_dir)) | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(self.abs_input_dir)) | 
					
						
							|  |  |  |         self.assertTrue(os.path.exists(self.rel_input_dir)) | 
					
						
							|  |  |  |         self.assertFalse(os.path.exists(self.yaml_input_dir))  # relative to user_path, not cwd | 
					
						
							| 
									
										
										
										
											2022-04-24 12:08:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  |     def test_generate_absolute(self): | 
					
						
							|  |  |  |         sys.argv = [sys.argv[0], '--seed', '0', | 
					
						
							|  |  |  |                     '--player_files_path', str(self.abs_input_dir), | 
					
						
							|  |  |  |                     '--outputpath', self.output_tempdir.name] | 
					
						
							|  |  |  |         print(f'Testing Generate.py {sys.argv} in {os.getcwd()}') | 
					
						
							| 
									
										
										
										
											2024-06-16 03:27:06 +02:00
										 |  |  |         Main.main(*Generate.main()) | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertOutput(self.output_tempdir.name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generate_relative(self): | 
					
						
							|  |  |  |         sys.argv = [sys.argv[0], '--seed', '0', | 
					
						
							|  |  |  |                     '--player_files_path', str(self.rel_input_dir), | 
					
						
							|  |  |  |                     '--outputpath', self.output_tempdir.name] | 
					
						
							|  |  |  |         print(f'Testing Generate.py {sys.argv} in {os.getcwd()}') | 
					
						
							| 
									
										
										
										
											2024-06-16 03:27:06 +02:00
										 |  |  |         Main.main(*Generate.main()) | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertOutput(self.output_tempdir.name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generate_yaml(self): | 
					
						
							|  |  |  |         # override host.yaml | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:35 +02:00
										 |  |  |         from settings import get_settings | 
					
						
							|  |  |  |         from Utils import user_path, local_path | 
					
						
							|  |  |  |         settings = get_settings() | 
					
						
							|  |  |  |         # NOTE: until/unless we override settings.Group's setattr, we have to upcast the input dir here | 
					
						
							|  |  |  |         settings.generator.player_files_path = settings.generator.PlayerFilesPath(self.yaml_input_dir) | 
					
						
							|  |  |  |         settings.generator.players = 0 | 
					
						
							|  |  |  |         settings._filename = None  # don't write to disk | 
					
						
							|  |  |  |         user_path_backup = user_path.cached_path | 
					
						
							|  |  |  |         user_path.cached_path = local_path()  # test yaml is actually in local_path | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             sys.argv = [sys.argv[0], '--seed', '0', | 
					
						
							|  |  |  |                         '--outputpath', self.output_tempdir.name] | 
					
						
							|  |  |  |             print(f'Testing Generate.py {sys.argv} in {os.getcwd()}, player_files_path={self.yaml_input_dir}') | 
					
						
							| 
									
										
										
										
											2024-06-16 03:27:06 +02:00
										 |  |  |             Main.main(*Generate.main()) | 
					
						
							| 
									
										
										
										
											2023-07-05 22:39:35 +02:00
										 |  |  |         finally: | 
					
						
							|  |  |  |             user_path.cached_path = user_path_backup | 
					
						
							| 
									
										
										
										
											2022-04-01 01:09:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.assertOutput(self.output_tempdir.name) | 
					
						
							| 
									
										
										
										
											2024-10-30 17:18:30 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestGenerateWeights(TestGenerateMain): | 
					
						
							|  |  |  |     """Tests Generate.py using a weighted file to generate for multiple players.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # this test will probably break if something in generation is changed that affects the seed before the weights get processed | 
					
						
							|  |  |  |     # can be fixed by changing the expected_results dict | 
					
						
							|  |  |  |     generate_dir = TestGenerateMain.generate_dir | 
					
						
							|  |  |  |     run_dir = TestGenerateMain.run_dir | 
					
						
							|  |  |  |     abs_input_dir = Path(__file__).parent / "data" / "weights" | 
					
						
							|  |  |  |     rel_input_dir = abs_input_dir.relative_to(run_dir)  # directly supplied relative paths are relative to cwd | 
					
						
							|  |  |  |     yaml_input_dir = abs_input_dir.relative_to(generate_dir)  # yaml paths are relative to user_path | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # don't need to run these tests | 
					
						
							|  |  |  |     test_generate_absolute = None | 
					
						
							|  |  |  |     test_generate_relative = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_generate_yaml(self): | 
					
						
							|  |  |  |         from settings import get_settings | 
					
						
							|  |  |  |         from Utils import user_path, local_path | 
					
						
							|  |  |  |         settings = get_settings() | 
					
						
							|  |  |  |         settings.generator.player_files_path = settings.generator.PlayerFilesPath(self.yaml_input_dir) | 
					
						
							|  |  |  |         settings.generator.players = 5  # arbitrary number, should be enough | 
					
						
							|  |  |  |         settings._filename = None | 
					
						
							|  |  |  |         user_path_backup = user_path.cached_path | 
					
						
							|  |  |  |         user_path.cached_path = local_path() | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             sys.argv = [sys.argv[0], "--seed", "1"] | 
					
						
							|  |  |  |             namespace, seed = Generate.main() | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             user_path.cached_path = user_path_backup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # there's likely a better way to do this, but hardcode the results from seed 1 to ensure they're always this | 
					
						
							|  |  |  |         expected_results = { | 
					
						
							|  |  |  |             "accessibility": [0, 2, 0, 2, 2], | 
					
						
							|  |  |  |             "progression_balancing": [0, 50, 99, 0, 50], | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.assertEqual(seed, 1) | 
					
						
							|  |  |  |         for option_name, results in expected_results.items(): | 
					
						
							|  |  |  |             for player, result in enumerate(results, 1): | 
					
						
							|  |  |  |                 self.assertEqual( | 
					
						
							|  |  |  |                     result, getattr(namespace, option_name)[player].value, | 
					
						
							|  |  |  |                     "Generated results from weights file did not match expected value." | 
					
						
							|  |  |  |                 ) |