mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
e6496df595
feat: Add multiple projects support feat: enhanced read_note for when initial result is not found fix: merge frontmatter when updating note fix: handle directory removed on sync watch
159 lines
5.1 KiB
Python
159 lines
5.1 KiB
Python
"""Tests for project CLI commands."""
|
|
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
|
|
import pytest
|
|
from typer.testing import CliRunner
|
|
|
|
from basic_memory.cli.main import app
|
|
from basic_memory.config import ConfigManager, DATA_DIR_NAME, CONFIG_FILE_NAME
|
|
|
|
|
|
@pytest.fixture
|
|
def temp_home(monkeypatch):
|
|
"""Create a temporary directory for testing."""
|
|
with TemporaryDirectory() as tempdir:
|
|
temp_home = Path(tempdir)
|
|
monkeypatch.setattr(Path, "home", lambda: temp_home)
|
|
|
|
# Ensure config directory exists
|
|
config_dir = temp_home / DATA_DIR_NAME
|
|
config_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
yield temp_home
|
|
|
|
|
|
@pytest.fixture
|
|
def cli_runner():
|
|
"""Create a CLI runner for testing."""
|
|
return CliRunner()
|
|
|
|
|
|
def test_project_list_empty(cli_runner, temp_home):
|
|
"""Test listing projects when none are configured."""
|
|
# Create empty config but with main project (will always be present)
|
|
config_file = temp_home / DATA_DIR_NAME / CONFIG_FILE_NAME
|
|
config_file.write_text(json.dumps({"projects": {}, "default_project": "main"}))
|
|
|
|
# Run command
|
|
result = cli_runner.invoke(app, ["project", "list"])
|
|
assert result.exit_code == 0
|
|
# The test will always have at least the "main" project due to auto-initialization
|
|
assert "main" in result.stdout
|
|
|
|
|
|
def test_project_list(cli_runner, temp_home):
|
|
"""Test listing projects."""
|
|
# Create config with projects
|
|
config_file = temp_home / DATA_DIR_NAME / CONFIG_FILE_NAME
|
|
config_data = {
|
|
"projects": {
|
|
"main": str(temp_home / "basic-memory"),
|
|
"work": str(temp_home / "work-memory"),
|
|
},
|
|
"default_project": "main",
|
|
}
|
|
config_file.write_text(json.dumps(config_data))
|
|
|
|
# Run command
|
|
result = cli_runner.invoke(app, ["project", "list"])
|
|
assert result.exit_code == 0
|
|
assert "main" in result.stdout
|
|
assert "work" in result.stdout
|
|
assert "basic-memory" in result.stdout
|
|
assert "work-memory" in result.stdout
|
|
|
|
|
|
def test_project_add(cli_runner, temp_home):
|
|
"""Test adding a project."""
|
|
# Create config manager to initialize config
|
|
config_manager = ConfigManager()
|
|
|
|
# Create a project directory
|
|
test_project_dir = temp_home / "test-project"
|
|
|
|
# Run command
|
|
result = cli_runner.invoke(app, ["project", "add", "test", str(test_project_dir)])
|
|
assert result.exit_code == 0
|
|
assert "Project 'test' added at" in result.stdout
|
|
|
|
# Verify project was added
|
|
config_manager = ConfigManager()
|
|
assert "test" in config_manager.projects
|
|
assert Path(config_manager.projects["test"]) == test_project_dir
|
|
|
|
|
|
def test_project_add_existing(cli_runner, temp_home):
|
|
"""Test adding a project that already exists."""
|
|
# Create config manager and add a project
|
|
config_manager = ConfigManager()
|
|
config_manager.add_project("test", str(temp_home / "test-project"))
|
|
|
|
# Try to add the same project again
|
|
result = cli_runner.invoke(app, ["project", "add", "test", str(temp_home / "another-path")])
|
|
assert result.exit_code == 1
|
|
assert "Error: Project 'test' already exists" in result.stdout
|
|
|
|
|
|
def test_project_remove(cli_runner, temp_home):
|
|
"""Test removing a project."""
|
|
# Create config manager and add a project
|
|
config_manager = ConfigManager()
|
|
config_manager.add_project("test", str(temp_home / "test-project"))
|
|
|
|
# Remove the project
|
|
result = cli_runner.invoke(app, ["project", "remove", "test"])
|
|
assert result.exit_code == 0
|
|
assert "Project 'test' removed" in result.stdout
|
|
|
|
# Verify project was removed
|
|
config_manager = ConfigManager()
|
|
assert "test" not in config_manager.projects
|
|
|
|
|
|
def test_project_default(cli_runner, temp_home):
|
|
"""Test setting the default project."""
|
|
# Create config manager and add a project
|
|
config_manager = ConfigManager()
|
|
config_manager.add_project("test", str(temp_home / "test-project"))
|
|
|
|
# Set as default
|
|
result = cli_runner.invoke(app, ["project", "default", "test"])
|
|
assert result.exit_code == 0
|
|
assert "Project 'test' set as default" in result.stdout
|
|
|
|
# Verify default was set
|
|
config_manager = ConfigManager()
|
|
assert config_manager.default_project == "test"
|
|
|
|
|
|
def test_project_current(cli_runner, temp_home):
|
|
"""Test showing the current project."""
|
|
|
|
# Set as default
|
|
result = cli_runner.invoke(app, ["project", "current"])
|
|
assert result.exit_code == 0
|
|
assert "Current project: main" in result.stdout
|
|
assert "Path:" in result.stdout
|
|
assert "Database:" in result.stdout
|
|
|
|
|
|
def test_project_option(cli_runner, temp_home, monkeypatch):
|
|
"""Test using the --project option."""
|
|
# Create config manager and add a project
|
|
config_manager = ConfigManager()
|
|
config_manager.add_project("test", str(temp_home / "test-project"))
|
|
|
|
# Mock environment to capture the set variable
|
|
env_vars = {}
|
|
monkeypatch.setattr(os, "environ", env_vars)
|
|
|
|
# Run command with --project option
|
|
cli_runner.invoke(app, ["--project", "test", "project", "current"])
|
|
|
|
# Verify environment variable was set
|
|
assert env_vars.get("BASIC_MEMORY_PROJECT") == "test"
|