diff options
Diffstat (limited to 'packages/meshbay-node/tests/test_cli_dispatch.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_cli_dispatch.py | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/packages/meshbay-node/tests/test_cli_dispatch.py b/packages/meshbay-node/tests/test_cli_dispatch.py index a0b2a64..d73dfcf 100644 --- a/packages/meshbay-node/tests/test_cli_dispatch.py +++ b/packages/meshbay-node/tests/test_cli_dispatch.py @@ -13,10 +13,12 @@ is tested in `test_ops.py` and `test_roster_pairing.py`. What this catches is a branch nobody ever ran. """ +import re import sys import pytest from meshbay_node import daemon as daemon_mod +from node_source import cli_source # Each verb, with the arguments that reach its branch. `--yes` where the command # would otherwise stop for a confirmation nobody can type in a test. @@ -151,18 +153,22 @@ def test_every_verb_reaches_its_branch(argv, stub_daemon, monkeypatch, capsys): assert out.out or out.err, f"{' '.join(argv)} printed nothing at all" -def test_the_verb_list_here_matches_the_parser(): +def test_the_verb_list_here_matches_the_parser(monkeypatch, capsys): """ A verb added to the parser and not to this file would go untested, which is exactly how `reload` shipped broken. - """ - import inspect - source = inspect.getsource(daemon_mod.main) - start = source.index('choices=[') + len('choices=[') - end = source.index(']', start) - declared = {c.strip().strip('"\'') for c in source[start:end].split(',') - if c.strip()} + The verbs are read from what `--help` prints, not from the source, so this + holds wherever the parser is built. + """ + monkeypatch.setattr(sys, "argv", ["meshbay-node", "--help"]) + with pytest.raises(SystemExit): + daemon_mod.main() + usage = capsys.readouterr().out + groups = [g for g in re.findall(r"\{([\w,-]+)\}", usage) + if "status" in g.split(",")] + assert groups, "--help no longer lists the verbs as {a,b,…}" + declared = set(groups[0].split(",")) exercised = {argv[0] for argv in VERBS} # `init` writes a config file and `calibrate-argon2` burns CPU for seconds; @@ -262,7 +268,7 @@ def test_a_bare_invocation_with_no_config_yet_exits_cleanly(monkeypatch, tmp_pat "a fresh, unprovisioned start must not create anything on disk") -def test_a_removed_verb_says_what_replaced_it(): +def test_a_removed_verb_says_what_replaced_it(stub_daemon, monkeypatch, capsys): """ `member upload` used to set a group-wide switch that no longer exists. It reached the usage line for the *other* member verbs — "usage: meshbay-node @@ -272,20 +278,20 @@ def test_a_removed_verb_says_what_replaced_it(): Naming it costs three lines and is the difference between an operator finding `root set --writable` and concluding the CLI is broken. """ - import inspect - source = inspect.getsource(daemon_mod.main) - start = source.index('if args.command == "member":') - block = source[start:source.index('if args.command == "group":', start)] + monkeypatch.setattr(sys, "argv", ["meshbay-node", "member", "upload"]) + with pytest.raises(SystemExit) as exc: + daemon_mod.main() + assert exc.value.code == 1 + guidance = capsys.readouterr().out - assert 'sub == "upload"' in block, ( + assert "usage: meshbay-node member upload" not in guidance, ( "`member upload` falls through to the generic usage line") - guidance = block[block.index('sub == "upload"'):] - guidance = guidance[:guidance.index("sys.exit")] assert "root set" in guidance and "--writable" in guidance, ( "the message does not name what replaced it") -def test_there_is_no_way_to_create_a_group_in_the_old_shape(): +def test_there_is_no_way_to_create_a_group_in_the_old_shape( + stub_daemon, monkeypatch, capsys): """ `--upload-dir` is gone, and documenting it as deprecated was the wrong answer — which is what it got at first. @@ -301,9 +307,16 @@ def test_there_is_no_way_to_create_a_group_in_the_old_shape(): only legitimate use. Writing it does not. """ import inspect - source = inspect.getsource(daemon_mod.main) - assert "--upload-dir" not in source, ( + assert "--upload-dir" not in cli_source(), ( "the CLI can still create a group in the pre-RO/RW shape") + # With the daemon stubbed: a parser that accepted the flag would otherwise + # go on and add the group on whatever node answers the loopback API. + monkeypatch.setattr(sys, "argv", ["meshbay-node", "group", "add", "g", + "--dir", "/tmp/a", "--upload-dir", "/tmp/b"]) + with pytest.raises(SystemExit) as exc: + daemon_mod.main() + assert exc.value.code == 2, "the parser accepts --upload-dir" + assert "--upload-dir" in capsys.readouterr().err from meshbay_node import ops params = inspect.signature(ops.attach_group).parameters |