diff options
| author | user <user@clank> | 2026-08-19 15:25:28 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-19 15:25:28 +0200 |
| commit | 49ac13f70aa3a9224e90699fe68d8463909239db (patch) | |
| tree | 303c3cee9492e23de6a1f0afc7b2feffeba5c6aa /tests | |
| parent | slosh: the logo flies into place -- a particle engine, statelessly (diff) | |
| download | slosh-49ac13f70aa3a9224e90699fe68d8463909239db.tar.gz slosh-49ac13f70aa3a9224e90699fe68d8463909239db.tar.xz slosh-49ac13f70aa3a9224e90699fe68d8463909239db.zip | |
slosh: layout files are *.layout, not *.layout.kdl
The old name argued that the extension should say how to read the
file. The argument lost to a collision: zellij speaks the same KDL
syntax under that same extension with a different schema, and to
anyone arriving from there .kdl said *whose* file it is -- naming the
wrong owner is worse than not naming the parser. So a layout is
x.layout, a project's is slosh.layout, the name says what the file is
and --check says how it was read. (It is still KDL underneath; point
your editor's highlighting at *.layout.)
Nobody's checked-in workspace vanishes on upgrade: the project scan
still finds slosh.layout.kdl, never writes it, and where both
spellings exist the new one wins, because two files disagreeing needs
one answer. The unparseable-file heuristic in --check learned the new
suffix -- it matched '.layout.' with a trailing dot, which the new
name no longer has.
The webdemo overlay moves with it (demo.layout), rebuilt and
boot-checked.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_config.py | 4 | ||||
| -rw-r--r-- | tests/test_layout_files.py | 2 | ||||
| -rw-r--r-- | tests/test_portable_layouts.py | 8 | ||||
| -rw-r--r-- | tests/test_workspaces.py | 46 |
4 files changed, 43 insertions, 17 deletions
diff --git a/tests/test_config.py b/tests/test_config.py index cb80829..84d73c7 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -713,8 +713,8 @@ def test_the_shipped_files_are_what_they_claim(): check( "config/config.kdl lints clean", conf.returncode == 0, repr(conf.stderr[:160]) ) - lay = root / "config" / "example.layout.kdl" - check("the example layout is named `*.layout.kdl`", lay.exists(), str(lay)) + lay = root / "config" / "example.layout" + check("the example layout is named `*.layout`", lay.exists(), str(lay)) exl = subprocess.run([BIN, "--check", str(lay)], capture_output=True, text=True) check("and it lints clean as a layout", exl.returncode == 0, repr(exl.stderr[:200])) out = subprocess.run( diff --git a/tests/test_layout_files.py b/tests/test_layout_files.py index 7bc8285..611c83d 100644 --- a/tests/test_layout_files.py +++ b/tests/test_layout_files.py @@ -287,7 +287,7 @@ def test_bad_layouts(): r = s.api("apply-layout", kdl="layout { }") check("a layout with no tabs is refused", not r["ok"], str(r)) - r = s.api("apply-layout", path="/nonexistent/layout.kdl") + r = s.api("apply-layout", path="/nonexistent/x.layout") check("a missing file is refused", not r["ok"], str(r)) check( diff --git a/tests/test_portable_layouts.py b/tests/test_portable_layouts.py index 5b3ccc0..12229ba 100644 --- a/tests/test_portable_layouts.py +++ b/tests/test_portable_layouts.py @@ -27,7 +27,7 @@ def project(name, text): root = tempfile.mkdtemp(prefix="slosh-proj-") d = os.path.join(root, name) os.makedirs(os.path.join(d, "src")) - path = os.path.join(d, "slosh.layout.kdl") + path = os.path.join(d, "slosh.layout") with open(path, "w") as f: f.write(text) return d, path @@ -234,7 +234,7 @@ layout { ) with Session(SH, layout=path) as s: first = s.api("dump-layout", tab=s.tabs()[0]["id"], relative_to=d)["kdl"] - again = os.path.join(d, "again.layout.kdl") + again = os.path.join(d, "again.layout") with open(again, "w") as f: f.write(first) with Session(SH, layout=again) as s2: @@ -278,7 +278,7 @@ layout { check("it names: " + want, want in said, said) check( "every problem carries a file and a line", - said.count("slosh.layout.kdl:") >= 6, + said.count("slosh.layout:") >= 6, said, ) @@ -325,7 +325,7 @@ def test_a_syntax_error_in_a_layout_is_reported_as_the_layout_it_is(): code, said = lint(path) check( "it says which file and which line the syntax broke on", - "slosh.layout.kdl:" in said and "unclosed" in said, + "slosh.layout:" in said and "unclosed" in said, said, ) check( diff --git a/tests/test_workspaces.py b/tests/test_workspaces.py index 3a0163d..d691fa2 100644 --- a/tests/test_workspaces.py +++ b/tests/test_workspaces.py @@ -1,6 +1,6 @@ """Workspaces: projects on disk, and the tabs they open as. -A *project* is a directory somebody works in -- one with a `slosh.layout.kdl` +A *project* is a directory somebody works in -- one with a `slosh.layout` saying what it needs, or a `.git` and nothing said yet. A *workspace* is the tab it occupies here, and membership is that tab's `purpose` in the `project:` namespace, so there is no second answer to "what is this tab" and a dumped @@ -48,7 +48,7 @@ def roots(**projects): if what == "git": os.makedirs(os.path.join(d, ".git"), exist_ok=True) elif what: - with open(os.path.join(d, "slosh.layout.kdl"), "w") as f: + with open(os.path.join(d, "slosh.layout"), "w") as f: f.write(what) cfg = os.path.join(base, "config.kdl") with open(cfg, "w") as f: @@ -70,6 +70,32 @@ def session(cfg, argv=None, **kw): # ---- discovery ------------------------------------------------------------- +def test_the_old_layout_spelling_is_still_found_never_preferred(): + """`slosh.layout.kdl` was the name before the extension collided with + zellij's. A checked-in workspace must not vanish on upgrade, so the scan + still finds the old spelling -- and where both exist, the new one wins, + because two files disagreeing needs one answer.""" + base, dev, cfg = roots(old=None, both=None) + with open(os.path.join(dev, "old", "slosh.layout.kdl"), "w") as f: + f.write(API_LAYOUT) + with open(os.path.join(dev, "both", "slosh.layout"), "w") as f: + f.write(API_LAYOUT) + with open(os.path.join(dev, "both", "slosh.layout.kdl"), "w") as f: + f.write(API_LAYOUT) + with session(cfg) as s: + got = {w["name"]: w for w in s.api("workspaces")["workspaces"]} + check( + "a project with only the old name is still a project", + "old" in got and got["old"]["layout"].endswith("slosh.layout.kdl"), + str(got.get("old")), + ) + check( + "where both spellings exist the new one wins", + "both" in got and got["both"]["layout"].endswith("/slosh.layout"), + str(got.get("both")), + ) + + def test_a_project_is_a_layout_file_or_a_git(): """Both, because `~/dev` with forty checkouts and three layout files would otherwise be a picker with three rows -- and a `.git` is exactly the project @@ -82,7 +108,7 @@ def test_a_project_is_a_layout_file_or_a_git(): check("a directory that is neither is not listed", "notes" not in got, str(got)) check( "the declared one names its file", - got["api"]["layout"].endswith("slosh.layout.kdl"), + got["api"]["layout"].endswith("slosh.layout"), str(got["api"]), ) check( @@ -208,7 +234,7 @@ def test_a_project_with_no_layout_opens_as_your_project_layout(): bind to whichever project is opening -- not to the directory the file lives in, which would open every project in ~/.config.""" base, dev, cfg = roots(web="git") - shared = os.path.join(base, "project.layout.kdl") + shared = os.path.join(base, "project.layout") with open(shared, "w") as f: f.write('layout { tab { pane purpose="agent:main"; pane cwd="src" } }\n') with open(cfg, "a") as f: @@ -303,7 +329,7 @@ def test_saving_a_tab_writes_a_portable_layout_file(): saved = s.api("save-workspace") check( "it says where it wrote", - saved["path"] == os.path.join(dev, "web", "slosh.layout.kdl"), + saved["path"] == os.path.join(dev, "web", "slosh.layout"), str(saved), ) check( @@ -554,7 +580,7 @@ def test_every_verb_has_a_bare_form(): wrote = bare1(s, "save-workspace") check( "save-workspace names the file it wrote", - "slosh.layout.kdl" in wrote, + "slosh.layout" in wrote, repr(wrote), ) check( @@ -588,7 +614,7 @@ def test_a_dumped_session_restores_workspace_membership(): with session(cfg) as s: r = s.api("open-workspace", name="api") whole = s.api("dump-layout")["kdl"] - restored = os.path.join(base, "session.layout.kdl") + restored = os.path.join(base, "session.layout") with open(restored, "w") as f: f.write(whole) with Session(SH, config=cfg, layout=restored, cols=100, rows=30) as s2: @@ -609,7 +635,7 @@ def test_the_picker_lists_projects_and_opens_one(): s.key("w") screen = s.snapshot().screen() check("it is titled as projects", "projects" in screen, screen) - check("a declared project shows its file", "slosh.layout.kdl" in screen, screen) + check("a declared project shows its file", "slosh.layout" in screen, screen) check("and one without says so", "no layout" in screen, screen) s.send("web") @@ -649,11 +675,11 @@ def test_saving_from_the_keyboard_says_what_it_did(): s.api("open-workspace", name="web") s.key("W") screen = s.snapshot().screen() - check("the toast names the file", "slosh.layout.kdl" in screen, screen) + check("the toast names the file", "slosh.layout" in screen, screen) check("and counts what it wrote", "1 pane" in screen, screen) check( "the file is there", - os.path.exists(os.path.join(dev, "web", "slosh.layout.kdl")), + os.path.exists(os.path.join(dev, "web", "slosh.layout")), screen, ) |
