import json from pathlib import Path import tempfile import unittest from unittest.mock import patch from engine import static_files, prompt_builder class StaticFilesTests(unittest.TestCase): def setUp(self): self.directory = tempfile.TemporaryDirectory() self.addCleanup(self.directory.cleanup) self.path = Path(self.directory.name) / 'character.json' static_files._CACHE.clear() self.addCleanup(static_files._CACHE.clear) def test_character_reads_once_and_returns_independent_nested_data(self): self.path.write_text('{"personality": ["curious"]}') original = Path.read_text with patch.object(prompt_builder, 'CHARACTERS_DIR', self.path.parent), patch.object( Path, 'read_text', autospec=True, side_effect=original ) as read: first = prompt_builder.load_character('character') first['personality'].append('changed') self.assertEqual(prompt_builder.load_character('character')['personality'], ['curious']) self.assertEqual(read.call_count, 1) def test_edit_replace_delete_and_invalid_json_do_not_return_stale_data(self): self.path.write_text('{"name":"a"}') self.assertEqual(static_files.load_static_json(self.path), {'name': 'a'}) self.path.write_text('{"name":"updated"}') self.assertEqual(static_files.load_static_json(self.path), {'name': 'updated'}) replacement = self.path.with_suffix('.new') replacement.write_text('{"name":"replacement"}') replacement.replace(self.path) self.assertEqual(static_files.load_static_json(self.path), {'name': 'replacement'}) self.path.write_text('{invalid') with self.assertRaises(json.JSONDecodeError): static_files.load_static_json(self.path) self.path.unlink() with self.assertRaises(FileNotFoundError): static_files.load_static_json(self.path) self.path.write_text('{}') self.assertEqual(static_files.load_static_json(self.path), {}) def test_prompt_text_is_cached_and_refreshes(self): self.path.write_text(' Türkçe\n') original = Path.read_text with patch.object(Path, 'read_text', autospec=True, side_effect=original) as read: for _ in range(2): self.assertEqual(static_files.load_static_text(self.path), ' Türkçe\n') self.assertEqual(read.call_count, 1) self.path.write_text('New prompt') self.assertEqual(static_files.load_static_text(self.path), 'New prompt') self.assertEqual(read.call_count, 2) def test_cache_evicts_least_recently_used_file(self): with patch.object(static_files, '_MAX_ENTRIES', 2): paths = [self.path.with_name(str(i)) for i in range(3)] for path in paths: path.write_text(path.name) for path in paths[:2]: static_files.load_static_text(path) static_files.load_static_text(paths[0]) static_files.load_static_text(paths[2]) self.assertEqual(len(static_files._CACHE), 2) self.assertNotIn((paths[1].resolve(), False), static_files._CACHE)