repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources15d ago| #1 | """CLI error handling regression tests.""" |
| #2 | |
| #3 | import json |
| #4 | import os |
| #5 | import subprocess |
| #6 | import sys |
| #7 | |
| #8 | |
| #9 | COMMANDS = [ |
| #10 | ( |
| #11 | ["store", "hello", "cli", "not-a-float"], |
| #12 | "importance must be a number", |
| #13 | ), |
| #14 | ( |
| #15 | ["recall", "hello", "not-an-int"], |
| #16 | "top_k must be an integer", |
| #17 | ), |
| #18 | ( |
| #19 | ["update", "missing-id", "new content", "not-a-float"], |
| #20 | "importance must be a number", |
| #21 | ), |
| #22 | ( |
| #23 | ["import", "missing-file.json"], |
| #24 | "Import file not found", |
| #25 | ), |
| #26 | ] |
| #27 | |
| #28 | |
| #29 | def run_cli(args, tmp_path): |
| #30 | env = os.environ.copy() |
| #31 | env["HOME"] = str(tmp_path / "home") |
| #32 | env["MNEMOSYNE_DATA_DIR"] = str(tmp_path / "mnemosyne-data") |
| #33 | return subprocess.run( |
| #34 | [sys.executable, "-m", "mnemosyne.cli", *args], |
| #35 | text=True, |
| #36 | capture_output=True, |
| #37 | env=env, |
| #38 | check=False, |
| #39 | ) |
| #40 | |
| #41 | |
| #42 | def test_import_hindsight_errors_return_nonzero_exit(tmp_path): |
| #43 | missing_file = tmp_path / "missing-hindsight-export.json" |
| #44 | |
| #45 | result = run_cli(["import-hindsight", str(missing_file)], tmp_path) |
| #46 | |
| #47 | assert result.returncode != 0 |
| #48 | assert "Traceback" not in result.stdout |
| #49 | assert "Traceback" not in result.stderr |
| #50 | payload = json.loads(result.stdout) |
| #51 | assert payload["provider"] == "hindsight" |
| #52 | assert payload["errors"] |
| #53 | assert "No such file or directory" in payload["errors"][0] |
| #54 | |
| #55 | |
| #56 | def test_invalid_cli_input_reports_error_without_traceback(tmp_path): |
| #57 | for args, expected_error in COMMANDS: |
| #58 | result = run_cli(args, tmp_path) |
| #59 | |
| #60 | assert result.returncode != 0, args |
| #61 | assert expected_error in result.stderr, result.stderr |
| #62 | assert "Traceback" not in result.stderr |
| #63 | |
| #64 | |
| #65 | def test_import_non_object_json_reports_error_without_traceback(tmp_path): |
| #66 | for payload in ("[]", '"not an export"'): |
| #67 | bad_export = tmp_path / "not-an-export.json" |
| #68 | bad_export.write_text(payload, encoding="utf-8") |
| #69 | |
| #70 | result = run_cli(["import", str(bad_export)], tmp_path) |
| #71 | |
| #72 | assert result.returncode != 0 |
| #73 | assert "Import file must contain a Mnemosyne export object" in result.stderr |
| #74 | assert "Traceback" not in result.stderr |
| #75 | |
| #76 | |
| #77 | def test_import_malformed_json_reports_error_without_traceback(tmp_path): |
| #78 | bad_json = tmp_path / "bad.json" |
| #79 | bad_json.write_text("{not valid json", encoding="utf-8") |
| #80 | |
| #81 | result = run_cli(["import", str(bad_json)], tmp_path) |
| #82 | |
| #83 | assert result.returncode != 0 |
| #84 | assert "Invalid JSON" in result.stderr |
| #85 | assert "Traceback" not in result.stderr |
| #86 | |
| #87 | |
| #88 | def test_export_reports_actual_exported_memory_counts(tmp_path): |
| #89 | store_result = run_cli(["store", "exported memory", "cli", "0.7"], tmp_path) |
| #90 | assert store_result.returncode == 0, store_result.stderr |
| #91 | |
| #92 | export_path = tmp_path / "export.json" |
| #93 | result = run_cli(["export", str(export_path)], tmp_path) |
| #94 | |
| #95 | assert result.returncode == 0, result.stderr |
| #96 | assert "Exported 1 working, 0 episodic, 1 legacy, 2 triples" in result.stdout |
| #97 | assert "Exported 0 memories" not in result.stdout |
| #98 | |
| #99 | exported = json.loads(export_path.read_text(encoding="utf-8")) |
| #100 | assert len(exported["working_memory"]) == 1 |
| #101 | assert len(exported["legacy_memories"]) == 1 |
| #102 | assert len(exported["triples"]) == 2 |
| #103 | |
| #104 | |
| #105 | def test_import_reports_actual_imported_memory_counts(tmp_path): |
| #106 | source_dir = tmp_path / "source" |
| #107 | import_dir = tmp_path / "imported" |
| #108 | |
| #109 | store_result = run_cli(["store", "imported memory", "cli", "0.7"], source_dir) |
| #110 | assert store_result.returncode == 0, store_result.stderr |
| #111 | |
| #112 | export_path = tmp_path / "export.json" |
| #113 | export_result = run_cli(["export", str(export_path)], source_dir) |
| #114 | assert export_result.returncode == 0, export_result.stderr |
| #115 | |
| #116 | result = run_cli(["import", str(export_path)], import_dir) |
| #117 | |
| #118 | assert result.returncode == 0, result.stderr |
| #119 | assert "Imported 1 working, 0 episodic, 1 legacy, 2 triples" in result.stdout |
| #120 | assert "Imported 0 memories" not in result.stdout |
| #121 | |
| #122 | |
| #123 | def test_bank_cli_list_create_delete_uses_configured_data_dir(tmp_path): |
| #124 | result = run_cli(["bank", "list"], tmp_path) |
| #125 | assert result.returncode == 0, result.stderr |
| #126 | assert "default" in result.stdout |
| #127 | assert "Traceback" not in result.stderr |
| #128 | |
| #129 | result = run_cli(["bank", "create", "project_a"], tmp_path) |
| #130 | assert result.returncode == 0, result.stderr |
| #131 | assert "Created bank: project_a" in result.stdout |
| #132 | assert "Traceback" not in result.stderr |
| #133 | |
| #134 | result = run_cli(["bank", "list"], tmp_path) |
| #135 | assert result.returncode == 0, result.stderr |
| #136 | assert "project_a" in result.stdout |
| #137 | |
| #138 | result = run_cli(["bank", "delete", "project_a"], tmp_path) |
| #139 | assert result.returncode == 0, result.stderr |
| #140 | assert "Deleted bank: project_a" in result.stdout |
| #141 | assert "Traceback" not in result.stderr |
| #142 | |
| #143 | |
| #144 | def test_bank_cli_validation_errors_are_user_facing(tmp_path): |
| #145 | cases = [ |
| #146 | (["bank", "create", "bad/name"], "Invalid bank name", 2), |
| #147 | (["bank", "create"], "Usage: mnemosyne bank create <name>", 2), |
| #148 | (["bank", "delete"], "Usage: mnemosyne bank delete <name>", 2), |
| #149 | (["bank", "nope"], "Unknown bank command: nope", 2), |
| #150 | (["bank", "delete", "missing_bank"], "Bank not found: missing_bank", 1), |
| #151 | ] |
| #152 | |
| #153 | for args, expected_error, expected_returncode in cases: |
| #154 | result = run_cli(args, tmp_path) |
| #155 | |
| #156 | assert result.returncode == expected_returncode, args |
| #157 | assert result.stdout == "" |
| #158 | assert expected_error in result.stderr |
| #159 | assert "Traceback" not in result.stderr |
| #160 |