"""CLI parsing tests — argv → (subcommand, Namespace) and → Args.""" from __future__ import annotations import pytest from cloud_sync.cli import Args, args_from, parse # ---- pull / push ---- def test_parses_pull_without_url() -> None: """url is sync.json's job now — pull/push don't take --url.""" cmd, ns = parse(["pull"]) assert cmd == "pull" args = args_from(ns) assert isinstance(args, Args) assert args.allow_download is True assert args.headless is False assert args.instance_label is None def test_default_token_file_under_pack_folder() -> None: _, ns = parse(["pull", "--pack-folder=/tmp/inst"]) args = args_from(ns) assert args.token_file.as_posix().endswith(".cloud-sync/token") assert "/tmp/inst" in args.token_file.as_posix() def test_custom_token_file_overrides_default() -> None: _, ns = parse([ "pull", "--pack-folder=/tmp/inst", "--token-file=/etc/cloud-creds", ]) args = args_from(ns) assert args.token_file.as_posix() == "/etc/cloud-creds" def test_inline_and_space_separated_both_work() -> None: _, ns1 = parse(["pull", "--pack-folder=/srv"]) _, ns2 = parse(["pull", "--pack-folder", "/srv"]) a1, a2 = args_from(ns1), args_from(ns2) assert a1.pack_folder == a2.pack_folder def test_no_gui_flag() -> None: _, a = parse(["push", "-g"]) assert args_from(a).headless is True _, b = parse(["push", "--no-gui"]) assert args_from(b).headless is True def test_no_download_flag() -> None: _, ns = parse(["push", "--no-download"]) assert args_from(ns).allow_download is False def test_restic_binary_override() -> None: _, ns = parse(["push", "--restic-binary=/opt/restic"]) a = args_from(ns) assert a.restic_binary is not None assert a.restic_binary.as_posix() == "/opt/restic" def test_instance_label_override() -> None: _, ns = parse(["pull", "--instance-label=Frazaserver 1.21.4"]) assert args_from(ns).instance_label == "Frazaserver 1.21.4" def test_pack_folder_is_resolved_to_absolute() -> None: _, ns = parse(["pull", "--pack-folder=."]) assert args_from(ns).pack_folder.is_absolute() # ---- setup / init / disable ---- def test_setup_subcommand_accepts_optional_url() -> None: cmd, ns = parse(["setup", "--url=https://x"]) assert cmd == "setup" assert ns.url == "https://x" def test_init_requires_url() -> None: with pytest.raises(SystemExit): parse(["init"]) def test_init_accepts_url_and_token() -> None: cmd, ns = parse(["init", "--url=https://x", "--token=42:secret"]) assert cmd == "init" assert ns.url == "https://x" assert ns.token == "42:secret" def test_disable_subcommand_parses() -> None: cmd, ns = parse(["disable", "--pack-folder=/tmp/x"]) assert cmd == "disable" assert str(ns.pack_folder) == "/tmp/x" def test_enable_subcommand_parses() -> None: cmd, ns = parse(["enable", "--pack-folder=/tmp/x"]) assert cmd == "enable" assert str(ns.pack_folder) == "/tmp/x" def test_missing_subcommand_exits() -> None: with pytest.raises(SystemExit): parse([]) def test_unknown_subcommand_exits() -> None: with pytest.raises(SystemExit): parse(["bogus"])