diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-16 01:06:03 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-16 01:06:03 +0200 |
| commit | d5933448cf7c8186afbcf4d52fccd16d1b827a5c (patch) | |
| tree | 8dcda6dedf7654f316b968bcc33552b8b05e0dcc /packages/meshbay-hub/tests/test_files_sorting.py | |
| parent | 1f84c047914cf21df1a1de196d990d193539523d (diff) | |
| download | meshbay-d5933448cf7c8186afbcf4d52fccd16d1b827a5c.tar.gz | |
fix(hub): the Files listing sorts its folders by the chosen column too
Folders were always ordered by name, whatever the column and direction, so
reversing the name sort or sorting by size moved only the files. A folder's
size is what it holds and its date its newest file; ties go to the name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests/test_files_sorting.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_files_sorting.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_files_sorting.py b/packages/meshbay-hub/tests/test_files_sorting.py new file mode 100644 index 0000000..730d1e8 --- /dev/null +++ b/packages/meshbay-hub/tests/test_files_sorting.py @@ -0,0 +1,84 @@ +""" +Sorting the Files listing (`files-app.js`). + +Reported: reversing the name sort, or sorting by size, did nothing — above all +with folders. Folders were `[...dirs].sort()` whatever the column, so only the +files below them moved, and a folder full of folders did not move at all. + +Both halves now go through one `sortRows`, run here out of the source. +""" + +import json +import re +import shutil +import subprocess +from pathlib import Path + +import pytest + +STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static" +FILES_APP = STATIC / "files-app.js" + +pytestmark = pytest.mark.skipif( + shutil.which("node") is None or not FILES_APP.exists(), + reason="node or the SPA sources are not available") + + +@pytest.fixture(scope="module") +def source(): + m = re.search(r"^function sortRows\(.*?^\}", FILES_APP.read_text(encoding="utf-8"), + re.M | re.S) + assert m, "sortRows is no longer where this test reads it from" + return m.group(0) + + +def _names(tmp_path, source, rows, key, asc): + script = tmp_path / "case.js" + script.write_text( + f"{source}\nconsole.log(JSON.stringify(" + f"sortRows({json.dumps(rows)}, {json.dumps(key)}, {json.dumps(asc)}).map((r) => r.name)));", + encoding="utf-8") + out = subprocess.run(["node", str(script)], capture_output=True, text=True, check=True) + return json.loads(out.stdout) + + +FOLDERS = [ + {"name": "Beta", "size": 10, "date": 300}, + {"name": "alpha", "size": 500, "date": 100}, + {"name": "Gamma", "size": 0, "date": 0}, + {"name": "delta", "size": 500, "date": 200}, +] + + +def test_name_both_ways(tmp_path, source): + up = _names(tmp_path, source, FOLDERS, "name", True) + assert up == ["alpha", "Beta", "delta", "Gamma"] + assert _names(tmp_path, source, FOLDERS, "name", False) == up[::-1] + + +def test_size_both_ways_with_ties_broken_by_name(tmp_path, source): + assert _names(tmp_path, source, FOLDERS, "size", True) == ["Gamma", "Beta", "alpha", "delta"] + assert _names(tmp_path, source, FOLDERS, "size", False) == ["alpha", "delta", "Beta", "Gamma"] + + +def test_date(tmp_path, source): + assert _names(tmp_path, source, FOLDERS, "date", False) == ["Beta", "delta", "alpha", "Gamma"] + + +def test_folders_have_no_type_and_fall_back_to_their_names(tmp_path, source): + assert _names(tmp_path, source, FOLDERS, "type", False) == ["alpha", "Beta", "delta", "Gamma"] + + +def test_a_missing_size_sorts_as_zero_rather_than_breaking_the_order(tmp_path, source): + rows = [{"name": "b", "size": 5}, {"name": "a"}, {"name": "c", "size": 1}] + assert _names(tmp_path, source, rows, "size", True) == ["a", "c", "b"] + + +def test_folders_and_files_share_one_ordering(): + """Both lists in the listing are ordered by the same function and column.""" + text = FILES_APP.read_text(encoding="utf-8") + # Code lines only: the comment above sortRows quotes the old line on purpose. + code = "\n".join(line for line in text.splitlines() if not line.lstrip().startswith("//")) + assert "[...dirs].sort()" not in code + assert re.search(r"const sorted = sortRows\(", text) + assert re.search(r"const subdirs = sortRows\(", text) |