diff --git a/tests/test_init_gitignore_protection.py b/tests/test_init_gitignore_protection.py index ab22ea3..6fb7499 100644 --- a/tests/test_init_gitignore_protection.py +++ b/tests/test_init_gitignore_protection.py @@ -7,6 +7,7 @@ the two filenames to `.gitignore` when `` is a git repository. """ from pathlib import Path +from unittest.mock import mock_open, patch from mempalace.cli import _ensure_mempalace_files_gitignored @@ -60,3 +61,20 @@ def test_handles_gitignore_without_trailing_newline(tmp_path): assert "dist\n" in contents assert "mempalace.yaml" in contents assert "entities.json" in contents + + +def test_gitignore_io_pins_utf8_and_defensive_decode(tmp_path): + """Regression for #1648: never fall back to the Windows locale codec.""" + _git_init(tmp_path) + gitignore = tmp_path / ".gitignore" + gitignore.write_text("# café\n", encoding="utf-8") + append_handle = mock_open() + + with ( + patch.object(Path, "read_text", return_value="# café\n") as read_text, + patch("builtins.open", append_handle), + ): + assert _ensure_mempalace_files_gitignored(tmp_path) is True + + read_text.assert_called_once_with(encoding="utf-8", errors="replace") + append_handle.assert_called_once_with(gitignore, "a", encoding="utf-8") diff --git a/tests/test_layers.py b/tests/test_layers.py index d4c54ce..56263a3 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -201,6 +201,27 @@ def test_layer1_importance_from_various_keys(): assert "ESSENTIAL STORY" in result +def test_layer1_breaks_importance_ties_by_filed_at_recency(): + """Equal-importance drawers surface newest-first instead of insertion order.""" + docs = ["oldest memory", "newest memory", "middle memory"] + metas = [ + {"room": "moments", "importance": 3, "filed_at": "2026-01-01T00:00:00Z"}, + {"room": "moments", "importance": 3, "filed_at": "2026-03-01T00:00:00Z"}, + {"room": "moments", "importance": 3, "filed_at": "2026-02-01T00:00:00Z"}, + ] + mock_col = _mock_chromadb_for_layer(docs, metas) + + with ( + patch("mempalace.layers.MempalaceConfig") as mock_cfg, + patch("mempalace.layers._get_collection", return_value=mock_col), + ): + mock_cfg.return_value.palace_path = "/fake" + result = Layer1(palace_path="/fake").generate() + + assert result.index("newest memory") < result.index("middle memory") + assert result.index("middle memory") < result.index("oldest memory") + + def test_layer1_batch_exception_breaks(): """If col.get raises on a batch, loop breaks gracefully.""" mock_col = MagicMock()