feat(desktop): launch packaged gui builds by default
This commit is contained in:
@@ -16,6 +16,7 @@ from hermes_cli import main as cli_main
|
||||
def _ns(**kw):
|
||||
defaults = dict(
|
||||
skip_build=False,
|
||||
source=False,
|
||||
fake_boot=False,
|
||||
ignore_existing=False,
|
||||
hermes_root=None,
|
||||
@@ -33,26 +34,41 @@ def _make_desktop_tree(tmp_path: Path) -> Path:
|
||||
return root
|
||||
|
||||
|
||||
def test_gui_installs_builds_and_launches_desktop(tmp_path, monkeypatch):
|
||||
def _make_packaged_executable(root: Path, monkeypatch, platform: str = "darwin") -> Path:
|
||||
monkeypatch.setattr(cli_main.sys, "platform", platform)
|
||||
desktop_dir = root / "apps" / "desktop"
|
||||
if platform == "darwin":
|
||||
exe = desktop_dir / "release" / "mac-arm64" / "Hermes.app" / "Contents" / "MacOS" / "Hermes"
|
||||
elif platform == "win32":
|
||||
exe = desktop_dir / "release" / "win-unpacked" / "Hermes.exe"
|
||||
else:
|
||||
exe = desktop_dir / "release" / "linux-unpacked" / "hermes"
|
||||
exe.parent.mkdir(parents=True)
|
||||
exe.write_text("", encoding="utf-8")
|
||||
return exe
|
||||
|
||||
|
||||
def test_gui_installs_packages_and_launches_desktop_app(tmp_path, monkeypatch):
|
||||
root = _make_desktop_tree(tmp_path)
|
||||
desktop_dir = root / "apps" / "desktop"
|
||||
monkeypatch.setattr(cli_main, "PROJECT_ROOT", root)
|
||||
packaged_exe = _make_packaged_executable(root, monkeypatch)
|
||||
|
||||
install_ok = subprocess.CompletedProcess(["npm", "ci"], 0)
|
||||
build_ok = subprocess.CompletedProcess(["npm", "run", "build"], 0)
|
||||
launch_ok = subprocess.CompletedProcess(["npm", "exec", "--", "electron", "."], 0)
|
||||
pack_ok = subprocess.CompletedProcess(["npm", "run", "pack"], 0)
|
||||
launch_ok = subprocess.CompletedProcess([str(packaged_exe)], 0)
|
||||
|
||||
with patch("hermes_cli.main.shutil.which", return_value="/usr/bin/npm"), \
|
||||
patch("hermes_cli.main._run_npm_install_deterministic", return_value=install_ok) as mock_install, \
|
||||
patch("hermes_cli.main.subprocess.run", side_effect=[build_ok, launch_ok]) as mock_run, \
|
||||
patch("hermes_cli.main.subprocess.run", side_effect=[pack_ok, launch_ok]) as mock_run, \
|
||||
pytest.raises(SystemExit) as exc:
|
||||
cli_main.cmd_gui(_ns())
|
||||
|
||||
assert exc.value.code == 0
|
||||
mock_install.assert_called_once_with("/usr/bin/npm", root, capture_output=False)
|
||||
assert mock_run.call_args_list[0].args[0] == ["/usr/bin/npm", "run", "build"]
|
||||
assert mock_run.call_args_list[0].args[0] == ["/usr/bin/npm", "run", "pack"]
|
||||
assert mock_run.call_args_list[0].kwargs["cwd"] == desktop_dir
|
||||
assert mock_run.call_args_list[1].args[0] == ["/usr/bin/npm", "exec", "--", "electron", "."]
|
||||
assert mock_run.call_args_list[1].args[0] == [str(packaged_exe)]
|
||||
assert mock_run.call_args_list[1].kwargs["cwd"] == desktop_dir
|
||||
|
||||
|
||||
@@ -63,6 +79,7 @@ def test_gui_forwards_desktop_environment_overrides(tmp_path, monkeypatch):
|
||||
hermes_root.mkdir()
|
||||
cwd.mkdir()
|
||||
monkeypatch.setattr(cli_main, "PROJECT_ROOT", root)
|
||||
_make_packaged_executable(root, monkeypatch)
|
||||
|
||||
ok = subprocess.CompletedProcess([], 0)
|
||||
|
||||
@@ -96,31 +113,27 @@ def test_gui_exits_when_npm_missing(tmp_path, monkeypatch, capsys):
|
||||
assert "npm was not found" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_gui_skip_build_requires_existing_dist(tmp_path, monkeypatch, capsys):
|
||||
def test_gui_skip_build_requires_existing_packaged_app(tmp_path, monkeypatch, capsys):
|
||||
root = _make_desktop_tree(tmp_path)
|
||||
monkeypatch.setattr(cli_main, "PROJECT_ROOT", root)
|
||||
monkeypatch.setattr(cli_main.sys, "platform", "darwin")
|
||||
|
||||
with patch("hermes_cli.main.shutil.which", return_value="/usr/bin/npm"), \
|
||||
pytest.raises(SystemExit) as exc:
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
cli_main.cmd_gui(_ns(skip_build=True))
|
||||
|
||||
assert exc.value.code == 1
|
||||
assert "no desktop dist found" in capsys.readouterr().out
|
||||
assert "no packaged desktop app" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_gui_skip_build_launches_existing_dist_without_install_or_build(tmp_path, monkeypatch):
|
||||
def test_gui_skip_build_launches_existing_packaged_app_without_npm(tmp_path, monkeypatch):
|
||||
root = _make_desktop_tree(tmp_path)
|
||||
desktop_dir = root / "apps" / "desktop"
|
||||
(desktop_dir / "dist").mkdir()
|
||||
(desktop_dir / "dist" / "index.html").write_text("<div></div>", encoding="utf-8")
|
||||
electron_pkg = root / "node_modules" / "electron"
|
||||
electron_pkg.mkdir(parents=True)
|
||||
(electron_pkg / "package.json").write_text("{}", encoding="utf-8")
|
||||
monkeypatch.setattr(cli_main, "PROJECT_ROOT", root)
|
||||
packaged_exe = _make_packaged_executable(root, monkeypatch)
|
||||
|
||||
launch_ok = subprocess.CompletedProcess(["npm", "exec", "--", "electron", "."], 0)
|
||||
launch_ok = subprocess.CompletedProcess([str(packaged_exe)], 0)
|
||||
|
||||
with patch("hermes_cli.main.shutil.which", return_value="/usr/bin/npm"), \
|
||||
with patch("hermes_cli.main.shutil.which", return_value=None), \
|
||||
patch("hermes_cli.main._run_npm_install_deterministic") as mock_install, \
|
||||
patch("hermes_cli.main.subprocess.run", return_value=launch_ok) as mock_run, \
|
||||
pytest.raises(SystemExit) as exc:
|
||||
@@ -129,7 +142,29 @@ def test_gui_skip_build_launches_existing_dist_without_install_or_build(tmp_path
|
||||
assert exc.value.code == 0
|
||||
mock_install.assert_not_called()
|
||||
mock_run.assert_called_once()
|
||||
assert mock_run.call_args.args[0] == ["/usr/bin/npm", "exec", "--", "electron", "."]
|
||||
assert mock_run.call_args.args[0] == [str(packaged_exe)]
|
||||
|
||||
|
||||
def test_gui_source_mode_uses_renderer_build_and_electron(tmp_path, monkeypatch):
|
||||
root = _make_desktop_tree(tmp_path)
|
||||
desktop_dir = root / "apps" / "desktop"
|
||||
monkeypatch.setattr(cli_main, "PROJECT_ROOT", root)
|
||||
|
||||
install_ok = subprocess.CompletedProcess(["npm", "ci"], 0)
|
||||
build_ok = subprocess.CompletedProcess(["npm", "run", "build"], 0)
|
||||
launch_ok = subprocess.CompletedProcess(["npm", "exec", "--", "electron", "."], 0)
|
||||
|
||||
with patch("hermes_cli.main.shutil.which", return_value="/usr/bin/npm"), \
|
||||
patch("hermes_cli.main._run_npm_install_deterministic", return_value=install_ok), \
|
||||
patch("hermes_cli.main.subprocess.run", side_effect=[build_ok, launch_ok]) as mock_run, \
|
||||
pytest.raises(SystemExit) as exc:
|
||||
cli_main.cmd_gui(_ns(source=True))
|
||||
|
||||
assert exc.value.code == 0
|
||||
assert mock_run.call_args_list[0].args[0] == ["/usr/bin/npm", "run", "build"]
|
||||
assert mock_run.call_args_list[0].kwargs["cwd"] == desktop_dir
|
||||
assert mock_run.call_args_list[1].args[0] == ["/usr/bin/npm", "exec", "--", "electron", "."]
|
||||
assert mock_run.call_args_list[1].kwargs["cwd"] == desktop_dir
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
Reference in New Issue
Block a user