pyquipu-test-utils 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyquipu_test_utils-0.1.0/.gitignore +75 -0
- pyquipu_test_utils-0.1.0/PKG-INFO +14 -0
- pyquipu_test_utils-0.1.0/pyproject.toml +30 -0
- pyquipu_test_utils-0.1.0/src/quipu/__init__.py +3 -0
- pyquipu_test_utils-0.1.0/src/quipu/test_utils/__init__.py +0 -0
- pyquipu_test_utils-0.1.0/src/quipu/test_utils/fixtures.py +143 -0
- pyquipu_test_utils-0.1.0/src/quipu/test_utils/fixtures.stitcher.yaml +24 -0
- pyquipu_test_utils-0.1.0/src/quipu/test_utils/helpers.py +418 -0
- pyquipu_test_utils-0.1.0/src/quipu/test_utils/helpers.stitcher.yaml +49 -0
- pyquipu_test_utils-0.1.0/stitcher.lock +422 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# tmpfiles
|
|
7
|
+
o.md
|
|
8
|
+
a.md
|
|
9
|
+
a
|
|
10
|
+
o
|
|
11
|
+
t
|
|
12
|
+
tmpfile
|
|
13
|
+
|
|
14
|
+
# Scaffoldings
|
|
15
|
+
context_builder.yml
|
|
16
|
+
context_builder.py
|
|
17
|
+
current_prompts
|
|
18
|
+
|
|
19
|
+
# Distribution / Packaging
|
|
20
|
+
.Python
|
|
21
|
+
build/
|
|
22
|
+
develop-eggs/
|
|
23
|
+
dist/
|
|
24
|
+
downloads/
|
|
25
|
+
eggs/
|
|
26
|
+
.eggs/
|
|
27
|
+
lib/
|
|
28
|
+
lib64/
|
|
29
|
+
parts/
|
|
30
|
+
sdist/
|
|
31
|
+
var/
|
|
32
|
+
wheels/
|
|
33
|
+
*.egg-info/
|
|
34
|
+
.installed.cfg
|
|
35
|
+
*.egg
|
|
36
|
+
|
|
37
|
+
# Virtual Environments
|
|
38
|
+
venv/
|
|
39
|
+
env/
|
|
40
|
+
.env
|
|
41
|
+
.venv/
|
|
42
|
+
|
|
43
|
+
# Testing
|
|
44
|
+
.tox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# IDEs
|
|
55
|
+
.idea/
|
|
56
|
+
.vscode/
|
|
57
|
+
*.swp
|
|
58
|
+
*.swo
|
|
59
|
+
|
|
60
|
+
# Project Specific
|
|
61
|
+
*.log
|
|
62
|
+
axon.log
|
|
63
|
+
# Ignore test vaults or scratchpads if created in root
|
|
64
|
+
vault/
|
|
65
|
+
temp/
|
|
66
|
+
scratch/
|
|
67
|
+
# --- Quipu Dev Infra ---
|
|
68
|
+
.envs/
|
|
69
|
+
.uv/
|
|
70
|
+
sandbox/
|
|
71
|
+
*.egg-info/
|
|
72
|
+
__pycache__/
|
|
73
|
+
.pytest_cache/
|
|
74
|
+
.coverage
|
|
75
|
+
htmlcov/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyquipu-test-utils
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Common testing utilities for the Quipu ecosystem.
|
|
5
|
+
Author-email: doucx <doucxldh@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Classifier: Framework :: Pytest
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Requires-Dist: pyquipu-bus~=0.1.0
|
|
12
|
+
Requires-Dist: pyquipu-engine~=0.1.0
|
|
13
|
+
Requires-Dist: pyquipu-interfaces~=0.1.0
|
|
14
|
+
Requires-Dist: typer
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pyquipu-test-utils"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [{ name="doucx", email="doucxldh@gmail.com" }]
|
|
9
|
+
description = "Common testing utilities for the Quipu ecosystem."
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Operating System :: OS Independent",
|
|
15
|
+
"Framework :: Pytest",
|
|
16
|
+
]
|
|
17
|
+
dependencies = [
|
|
18
|
+
"pyquipu-interfaces ~= 0.1.0",
|
|
19
|
+
"pyquipu-engine ~= 0.1.0",
|
|
20
|
+
"pyquipu-bus ~= 0.1.0",
|
|
21
|
+
"typer"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[tool.uv.sources]
|
|
25
|
+
pyquipu-interfaces = { workspace = true }
|
|
26
|
+
pyquipu-engine = { workspace = true }
|
|
27
|
+
pyquipu-bus = { workspace = true }
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build.targets.wheel]
|
|
30
|
+
packages = ["src/quipu"]
|
|
File without changes
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from unittest.mock import MagicMock
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from typer.testing import CliRunner
|
|
7
|
+
|
|
8
|
+
from quipu.engine.git_db import GitDB
|
|
9
|
+
from quipu.engine.git_object_storage import GitObjectHistoryReader, GitObjectHistoryWriter
|
|
10
|
+
from quipu.engine.state_machine import Engine
|
|
11
|
+
from quipu.test_utils.helpers import run_git_command
|
|
12
|
+
|
|
13
|
+
# --- Global & Core Fixtures ---
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def runner() -> CliRunner:
|
|
18
|
+
return CliRunner()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def git_workspace(tmp_path: Path) -> Path:
|
|
23
|
+
repo_path = tmp_path / "test_repo"
|
|
24
|
+
repo_path.mkdir()
|
|
25
|
+
subprocess.run(["git", "init"], cwd=repo_path, check=True, capture_output=True)
|
|
26
|
+
subprocess.run(["git", "config", "user.email", "test@quipu.dev"], cwd=repo_path, check=True)
|
|
27
|
+
subprocess.run(["git", "config", "user.name", "Quipu Test"], cwd=repo_path, check=True)
|
|
28
|
+
return repo_path
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def engine_instance(git_workspace: Path) -> Engine:
|
|
33
|
+
git_db = GitDB(git_workspace)
|
|
34
|
+
reader = GitObjectHistoryReader(git_db)
|
|
35
|
+
writer = GitObjectHistoryWriter(git_db)
|
|
36
|
+
engine = Engine(root_dir=git_workspace, db=git_db, reader=reader, writer=writer)
|
|
37
|
+
return engine
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# --- Application Layer Mocks ---
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.fixture
|
|
44
|
+
def mock_engine():
|
|
45
|
+
engine = MagicMock(spec=Engine)
|
|
46
|
+
# 设置基础属性以防止简单的 AttributeError
|
|
47
|
+
engine.root_dir = Path("/mock/root")
|
|
48
|
+
# 显式初始化 git_db
|
|
49
|
+
engine.git_db = MagicMock()
|
|
50
|
+
# 初始化状态属性
|
|
51
|
+
engine.current_node = None
|
|
52
|
+
engine.history_graph = {}
|
|
53
|
+
return engine
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.fixture
|
|
57
|
+
def mock_runtime():
|
|
58
|
+
# 延迟导入以避免循环依赖或在未安装 runtime 时报错
|
|
59
|
+
from quipu.runtime.executor import Executor
|
|
60
|
+
|
|
61
|
+
runtime = MagicMock(spec=Executor)
|
|
62
|
+
return runtime
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# --- CLI Layer Fixtures ---
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@pytest.fixture
|
|
69
|
+
def quipu_workspace(engine_instance: Engine):
|
|
70
|
+
return engine_instance.root_dir, engine_instance.git_db, engine_instance
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# --- Integration Layer Fixtures ---
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.fixture(scope="module")
|
|
77
|
+
def sync_test_environment(tmp_path_factory):
|
|
78
|
+
base_dir = tmp_path_factory.mktemp("sync_tests")
|
|
79
|
+
remote_path = base_dir / "remote.git"
|
|
80
|
+
user_a_path = base_dir / "user_a"
|
|
81
|
+
user_b_path = base_dir / "user_b"
|
|
82
|
+
|
|
83
|
+
# 1. Create bare remote
|
|
84
|
+
run_git_command(base_dir, ["init", "--bare", str(remote_path)])
|
|
85
|
+
|
|
86
|
+
# 2. Clone for User A
|
|
87
|
+
run_git_command(base_dir, ["clone", str(remote_path), str(user_a_path)])
|
|
88
|
+
run_git_command(user_a_path, ["config", "user.name", "User A"])
|
|
89
|
+
run_git_command(user_a_path, ["config", "user.email", "user.a@example.com"])
|
|
90
|
+
|
|
91
|
+
# 3. Clone for User B
|
|
92
|
+
run_git_command(base_dir, ["clone", str(remote_path), str(user_b_path)])
|
|
93
|
+
run_git_command(user_b_path, ["config", "user.name", "User B"])
|
|
94
|
+
run_git_command(user_b_path, ["config", "user.email", "user.b@example.com"])
|
|
95
|
+
|
|
96
|
+
# Add a dummy file to avoid issues with initial empty commits
|
|
97
|
+
(user_a_path / "README.md").write_text("Initial commit")
|
|
98
|
+
run_git_command(user_a_path, ["add", "README.md"])
|
|
99
|
+
run_git_command(user_a_path, ["commit", "-m", "Initial commit"])
|
|
100
|
+
run_git_command(user_a_path, ["push", "origin", "HEAD"])
|
|
101
|
+
run_git_command(user_b_path, ["pull"])
|
|
102
|
+
|
|
103
|
+
return remote_path, user_a_path, user_b_path
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# --- Runtime/Executor Layer Fixtures ---
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@pytest.fixture
|
|
110
|
+
def mock_runtime_bus(monkeypatch):
|
|
111
|
+
m_bus = MagicMock()
|
|
112
|
+
# 让 bus.get 返回传入的 msg_id,方便测试断言语义
|
|
113
|
+
m_bus.get.side_effect = lambda msg_id, **kwargs: msg_id
|
|
114
|
+
|
|
115
|
+
patch_targets = [
|
|
116
|
+
"quipu.runtime.executor.bus",
|
|
117
|
+
"quipu.runtime.plugin_loader.bus",
|
|
118
|
+
"quipu.acts.basic.bus",
|
|
119
|
+
"quipu.acts.check.bus",
|
|
120
|
+
"quipu.acts.git.bus",
|
|
121
|
+
"quipu.acts.memory.bus",
|
|
122
|
+
"quipu.acts.read.bus",
|
|
123
|
+
"quipu.acts.refactor.bus",
|
|
124
|
+
"quipu.acts.shell.bus",
|
|
125
|
+
]
|
|
126
|
+
for target in patch_targets:
|
|
127
|
+
monkeypatch.setattr(target, m_bus, raising=False)
|
|
128
|
+
return m_bus
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@pytest.fixture
|
|
132
|
+
def executor(tmp_path: Path):
|
|
133
|
+
from quipu.acts.basic import register as register_basic_acts
|
|
134
|
+
from quipu.runtime.executor import Executor
|
|
135
|
+
|
|
136
|
+
instance = Executor(root_dir=tmp_path, yolo=True)
|
|
137
|
+
register_basic_acts(instance)
|
|
138
|
+
return instance
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@pytest.fixture
|
|
142
|
+
def isolated_vault(executor) -> Path:
|
|
143
|
+
return executor.root_dir
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"engine_instance": |-
|
|
2
|
+
提供一个绑定到 git_workspace 的、功能完备的 Engine 实例。
|
|
3
|
+
"executor": |-
|
|
4
|
+
为运行时测试提供一个隔离的 Executor 实例。
|
|
5
|
+
"git_workspace": |-
|
|
6
|
+
提供一个已初始化 Git 的干净工作区路径。
|
|
7
|
+
"isolated_vault": |-
|
|
8
|
+
提供 Executor 实例的根工作目录。
|
|
9
|
+
"mock_engine": |-
|
|
10
|
+
提供一个模拟的 Engine 实例。
|
|
11
|
+
用于测试 Application 层在不触及真实 Git/文件系统的情况下的编排逻辑。
|
|
12
|
+
"mock_runtime": |-
|
|
13
|
+
提供一个模拟的 Runtime (Executor) 实例。
|
|
14
|
+
"mock_runtime_bus": |-
|
|
15
|
+
自动 patch 所有 runtime 模块中导入的 'bus' 实例。
|
|
16
|
+
"quipu_workspace": |-
|
|
17
|
+
为 CLI 测试提供 Engine 实例及其工作目录。
|
|
18
|
+
返回: (work_dir_path, git_db, engine)
|
|
19
|
+
"runner": |-
|
|
20
|
+
提供一个可复用的 CliRunner 实例。
|
|
21
|
+
"sync_test_environment": |-
|
|
22
|
+
Sets up a full sync test environment:
|
|
23
|
+
1. A bare remote repository.
|
|
24
|
+
2. Two user workspaces cloned from the remote.
|
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import re
|
|
3
|
+
import subprocess
|
|
4
|
+
import time
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, Dict, List, Optional, Set, Tuple
|
|
8
|
+
|
|
9
|
+
from typer.testing import CliRunner
|
|
10
|
+
|
|
11
|
+
from quipu.cli.main import app
|
|
12
|
+
from quipu.engine.state_machine import Engine
|
|
13
|
+
from quipu.interfaces.models import QuipuNode
|
|
14
|
+
from quipu.interfaces.storage import HistoryReader, HistoryWriter
|
|
15
|
+
|
|
16
|
+
# --- Constants ---
|
|
17
|
+
|
|
18
|
+
# The correct hash for an empty git tree.
|
|
19
|
+
EMPTY_TREE_HASH = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# --- Git-based Test Helpers ---
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def create_plan_node_with_change(engine: Engine, parent_hash: str, file_name: str, content: str, message: str) -> str:
|
|
26
|
+
(engine.root_dir / file_name).write_text(content)
|
|
27
|
+
new_hash = engine.git_db.get_tree_hash()
|
|
28
|
+
engine.create_plan_node(input_tree=parent_hash, output_tree=new_hash, plan_content=message)
|
|
29
|
+
return new_hash
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def create_capture_node_with_change(engine: Engine, file_name: str, content: str, message: str) -> str:
|
|
33
|
+
(engine.root_dir / file_name).write_text(content)
|
|
34
|
+
new_hash = engine.git_db.get_tree_hash()
|
|
35
|
+
engine.capture_drift(new_hash, message=message)
|
|
36
|
+
return new_hash
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# --- In-Memory Backend Mocks for Engine Testing ---
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class VirtualFileSystem:
|
|
43
|
+
def __init__(self):
|
|
44
|
+
self._files: Dict[str, str] = {}
|
|
45
|
+
|
|
46
|
+
def write(self, path: str, content: str):
|
|
47
|
+
self._files[path] = content
|
|
48
|
+
|
|
49
|
+
def read(self, path: str) -> Optional[str]:
|
|
50
|
+
return self._files.get(path)
|
|
51
|
+
|
|
52
|
+
def copy(self) -> "VirtualFileSystem":
|
|
53
|
+
new_vfs = VirtualFileSystem()
|
|
54
|
+
new_vfs._files = self._files.copy()
|
|
55
|
+
return new_vfs
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def files(self) -> Dict[str, str]:
|
|
59
|
+
return self._files
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class InMemoryDB:
|
|
63
|
+
def __init__(self):
|
|
64
|
+
self.vfs = VirtualFileSystem()
|
|
65
|
+
self.snapshots: Dict[str, VirtualFileSystem] = {EMPTY_TREE_HASH: VirtualFileSystem()}
|
|
66
|
+
self.nodes: Dict[str, QuipuNode] = {} # output_tree -> Node
|
|
67
|
+
|
|
68
|
+
def get_tree_hash(self) -> str:
|
|
69
|
+
if not self.vfs.files:
|
|
70
|
+
return EMPTY_TREE_HASH
|
|
71
|
+
|
|
72
|
+
sorted_files = sorted(self.vfs.files.items())
|
|
73
|
+
hasher = hashlib.sha1()
|
|
74
|
+
for path, content in sorted_files:
|
|
75
|
+
hasher.update(path.encode("utf-8"))
|
|
76
|
+
hasher.update(content.encode("utf-8"))
|
|
77
|
+
|
|
78
|
+
tree_hash = hasher.hexdigest()
|
|
79
|
+
if tree_hash not in self.snapshots:
|
|
80
|
+
self.snapshots[tree_hash] = self.vfs.copy()
|
|
81
|
+
return tree_hash
|
|
82
|
+
|
|
83
|
+
def checkout_tree(self, new_tree_hash: str, old_tree_hash: Optional[str] = None):
|
|
84
|
+
# InMemoryDB 总是执行“瞬间切换”,不需要模拟 diff 优化逻辑
|
|
85
|
+
tree_hash = new_tree_hash
|
|
86
|
+
if tree_hash not in self.snapshots:
|
|
87
|
+
raise FileNotFoundError(f"In-memory snapshot not found for hash: {tree_hash}")
|
|
88
|
+
self.vfs = self.snapshots[tree_hash].copy()
|
|
89
|
+
|
|
90
|
+
def get_diff_name_status(self, old_tree: str, new_tree: str) -> List[Tuple[str, str]]:
|
|
91
|
+
old_vfs = self.snapshots.get(old_tree, VirtualFileSystem()).files
|
|
92
|
+
new_vfs = self.snapshots.get(new_tree, VirtualFileSystem()).files
|
|
93
|
+
|
|
94
|
+
old_files = set(old_vfs.keys())
|
|
95
|
+
new_files = set(new_vfs.keys())
|
|
96
|
+
|
|
97
|
+
added = new_files - old_files
|
|
98
|
+
deleted = old_files - new_files
|
|
99
|
+
common = old_files & new_files
|
|
100
|
+
|
|
101
|
+
changes = []
|
|
102
|
+
for f in added:
|
|
103
|
+
changes.append(("A", f))
|
|
104
|
+
for f in deleted:
|
|
105
|
+
changes.append(("D", f))
|
|
106
|
+
for f in common:
|
|
107
|
+
if old_vfs[f] != new_vfs[f]:
|
|
108
|
+
changes.append(("M", f))
|
|
109
|
+
return sorted(changes)
|
|
110
|
+
|
|
111
|
+
def get_diff_stat(self, old_tree: str, new_tree: str) -> str:
|
|
112
|
+
changes = self.get_diff_name_status(old_tree, new_tree)
|
|
113
|
+
return "\n".join(f"{status}\t{path}" for status, path in changes)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class InMemoryHistoryManager(HistoryReader, HistoryWriter):
|
|
117
|
+
def __init__(self, db: InMemoryDB):
|
|
118
|
+
self.db = db # The db holds the single source of truth for nodes
|
|
119
|
+
|
|
120
|
+
def create_node(
|
|
121
|
+
self,
|
|
122
|
+
node_type: str,
|
|
123
|
+
input_tree: str,
|
|
124
|
+
output_tree: str,
|
|
125
|
+
content: str,
|
|
126
|
+
summary_override: Optional[str] = None,
|
|
127
|
+
**kwargs: Any,
|
|
128
|
+
) -> QuipuNode:
|
|
129
|
+
fake_commit_hash = hashlib.sha1(f"{output_tree}{content}{time.time()}".encode()).hexdigest()
|
|
130
|
+
|
|
131
|
+
node = QuipuNode(
|
|
132
|
+
commit_hash=fake_commit_hash,
|
|
133
|
+
input_tree=input_tree,
|
|
134
|
+
output_tree=output_tree,
|
|
135
|
+
timestamp=datetime.now(),
|
|
136
|
+
filename=Path(f"memory://{fake_commit_hash}"),
|
|
137
|
+
node_type=node_type,
|
|
138
|
+
content=content,
|
|
139
|
+
summary=summary_override or (content.splitlines()[0] if content else f"Node {output_tree[:7]}"),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Correctly link parent upon creation
|
|
143
|
+
if input_tree in self.db.nodes:
|
|
144
|
+
parent_node = self.db.nodes[input_tree]
|
|
145
|
+
node.parent = parent_node
|
|
146
|
+
parent_node.children.append(node)
|
|
147
|
+
|
|
148
|
+
self.db.nodes[output_tree] = node
|
|
149
|
+
return node
|
|
150
|
+
|
|
151
|
+
def load_all_nodes(self) -> List[QuipuNode]:
|
|
152
|
+
# The relationships are already built, just return the list
|
|
153
|
+
return sorted(list(self.db.nodes.values()), key=lambda n: n.timestamp)
|
|
154
|
+
|
|
155
|
+
def get_node_count(self) -> int:
|
|
156
|
+
return len(self.db.nodes)
|
|
157
|
+
|
|
158
|
+
def load_nodes_paginated(self, limit: int, offset: int) -> List[QuipuNode]:
|
|
159
|
+
all_nodes = sorted(self.db.nodes.values(), key=lambda n: n.timestamp, reverse=True)
|
|
160
|
+
return all_nodes[offset : offset + limit]
|
|
161
|
+
|
|
162
|
+
def find_nodes(
|
|
163
|
+
self,
|
|
164
|
+
summary_regex: Optional[str] = None,
|
|
165
|
+
node_type: Optional[str] = None,
|
|
166
|
+
limit: int = 10,
|
|
167
|
+
) -> List[QuipuNode]:
|
|
168
|
+
candidates = list(self.db.nodes.values())
|
|
169
|
+
|
|
170
|
+
if summary_regex:
|
|
171
|
+
try:
|
|
172
|
+
pattern = re.compile(summary_regex, re.IGNORECASE)
|
|
173
|
+
candidates = [node for node in candidates if pattern.search(node.summary)]
|
|
174
|
+
except re.error:
|
|
175
|
+
return []
|
|
176
|
+
|
|
177
|
+
if node_type:
|
|
178
|
+
candidates = [node for node in candidates if node.node_type == node_type]
|
|
179
|
+
|
|
180
|
+
candidates.sort(key=lambda n: n.timestamp, reverse=True)
|
|
181
|
+
return candidates[:limit]
|
|
182
|
+
|
|
183
|
+
def get_node_content(self, node: QuipuNode) -> str:
|
|
184
|
+
return node.content
|
|
185
|
+
|
|
186
|
+
def get_ancestor_output_trees(self, start_output_tree_hash: str) -> Set[str]:
|
|
187
|
+
ancestors = set()
|
|
188
|
+
if start_output_tree_hash not in self.db.nodes:
|
|
189
|
+
return ancestors
|
|
190
|
+
|
|
191
|
+
curr = self.db.nodes[start_output_tree_hash]
|
|
192
|
+
while curr and curr.parent:
|
|
193
|
+
parent_node = curr.parent
|
|
194
|
+
ancestors.add(parent_node.output_tree)
|
|
195
|
+
curr = parent_node
|
|
196
|
+
return ancestors
|
|
197
|
+
|
|
198
|
+
def get_descendant_output_trees(self, start_output_tree_hash: str) -> Set[str]:
|
|
199
|
+
descendants = set()
|
|
200
|
+
if start_output_tree_hash not in self.db.nodes:
|
|
201
|
+
return descendants
|
|
202
|
+
|
|
203
|
+
queue = [self.db.nodes[start_output_tree_hash]]
|
|
204
|
+
visited = {start_output_tree_hash}
|
|
205
|
+
|
|
206
|
+
while queue:
|
|
207
|
+
current_node = queue.pop(0)
|
|
208
|
+
for child in current_node.children:
|
|
209
|
+
if child.output_tree not in visited:
|
|
210
|
+
descendants.add(child.output_tree)
|
|
211
|
+
visited.add(child.output_tree)
|
|
212
|
+
queue.append(child)
|
|
213
|
+
return descendants
|
|
214
|
+
|
|
215
|
+
def get_node_position(self, output_tree_hash: str) -> int:
|
|
216
|
+
all_nodes = sorted(self.db.nodes.values(), key=lambda n: n.timestamp, reverse=True)
|
|
217
|
+
for i, node in enumerate(all_nodes):
|
|
218
|
+
if node.output_tree == output_tree_hash:
|
|
219
|
+
return i
|
|
220
|
+
return -1
|
|
221
|
+
|
|
222
|
+
def get_private_data(self, node_commit_hash: str) -> Optional[str]:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
def get_node_blobs(self, commit_hash: str) -> Dict[str, bytes]:
|
|
226
|
+
return {}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
# --- CLI/Integration Test Helpers ---
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def run_git_command(cwd: Path, args: list[str], check: bool = True) -> str:
|
|
233
|
+
result = subprocess.run(["git"] + args, cwd=cwd, capture_output=True, text=True, check=check)
|
|
234
|
+
return result.stdout.strip()
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def get_local_quipu_heads(work_dir: Path) -> set[str]:
|
|
238
|
+
refs_output = run_git_command(
|
|
239
|
+
work_dir, ["for-each-ref", "--format=%(objectname)", "refs/quipu/local/heads"], check=False
|
|
240
|
+
)
|
|
241
|
+
if not refs_output:
|
|
242
|
+
return set()
|
|
243
|
+
return set(refs_output.splitlines())
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def create_node_via_cli(runner: CliRunner, work_dir: Path, content: str) -> str:
|
|
247
|
+
heads_before = get_local_quipu_heads(work_dir)
|
|
248
|
+
|
|
249
|
+
# [FIX] Add an explicit title to the plan to ensure predictable node summary.
|
|
250
|
+
plan_title = f"Plan for {content}"
|
|
251
|
+
plan_file = work_dir / f"{content}.md"
|
|
252
|
+
plan_file.write_text(f"# {plan_title}\n\n~~~~~act\necho '{content}'\n~~~~~")
|
|
253
|
+
|
|
254
|
+
result = runner.invoke(app, ["run", str(plan_file), "--work-dir", str(work_dir), "-y"])
|
|
255
|
+
assert result.exit_code == 0
|
|
256
|
+
|
|
257
|
+
heads_after = get_local_quipu_heads(work_dir)
|
|
258
|
+
new_heads = heads_after - heads_before
|
|
259
|
+
|
|
260
|
+
if not new_heads:
|
|
261
|
+
raise AssertionError("No new Quipu nodes created.")
|
|
262
|
+
|
|
263
|
+
# If only 1 node created, return it.
|
|
264
|
+
if len(new_heads) == 1:
|
|
265
|
+
return new_heads.pop()
|
|
266
|
+
|
|
267
|
+
# If 2 nodes created (Capture + Plan), identify the Plan node by checking if
|
|
268
|
+
# the explicit title is present in the commit message.
|
|
269
|
+
for head in new_heads:
|
|
270
|
+
msg = run_git_command(work_dir, ["log", "-1", "--format=%B", head])
|
|
271
|
+
if plan_title in msg:
|
|
272
|
+
return head
|
|
273
|
+
|
|
274
|
+
raise AssertionError(f"Could not identify Plan node among {len(new_heads)} new heads: {new_heads}")
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# --- Engine/Component Test Helpers ---
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def create_branching_history(engine: Engine) -> Engine:
|
|
281
|
+
ws = engine.root_dir
|
|
282
|
+
(ws / "file.txt").write_text("v0")
|
|
283
|
+
h0 = engine.git_db.get_tree_hash()
|
|
284
|
+
engine.create_plan_node(EMPTY_TREE_HASH, h0, "plan 0", summary_override="Root Node")
|
|
285
|
+
(ws / "file.txt").write_text("v1")
|
|
286
|
+
h1 = engine.git_db.get_tree_hash()
|
|
287
|
+
engine.create_plan_node(h0, h1, "plan 1", summary_override="Linear Node 1")
|
|
288
|
+
(ws / "file.txt").write_text("v2")
|
|
289
|
+
h2 = engine.git_db.get_tree_hash()
|
|
290
|
+
engine.create_plan_node(h1, h2, "plan 2", summary_override="Branch Point")
|
|
291
|
+
engine.visit(h2)
|
|
292
|
+
(ws / "branch_a.txt").touch()
|
|
293
|
+
h3a = engine.git_db.get_tree_hash()
|
|
294
|
+
engine.create_plan_node(h2, h3a, "plan 3a", summary_override="Branch A change")
|
|
295
|
+
engine.visit(h3a)
|
|
296
|
+
engine.create_plan_node(h3a, h3a, "plan 4", summary_override="Summary Node")
|
|
297
|
+
engine.visit(h2)
|
|
298
|
+
(ws / "branch_b.txt").touch()
|
|
299
|
+
h3b = engine.git_db.get_tree_hash()
|
|
300
|
+
engine.create_plan_node(h2, h3b, "plan 3b", summary_override="Branch B change")
|
|
301
|
+
return engine
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def create_complex_link_history(engine: Engine) -> Engine:
|
|
305
|
+
ws = engine.root_dir
|
|
306
|
+
engine.create_plan_node(EMPTY_TREE_HASH, EMPTY_TREE_HASH, "plan sum", summary_override="Ancestor_Summary")
|
|
307
|
+
(ws / "f").write_text("v0")
|
|
308
|
+
h0 = engine.git_db.get_tree_hash()
|
|
309
|
+
engine.create_plan_node(EMPTY_TREE_HASH, h0, "plan 0", summary_override="Root")
|
|
310
|
+
(ws / "f").write_text("v1")
|
|
311
|
+
h1 = engine.git_db.get_tree_hash()
|
|
312
|
+
engine.create_plan_node(h0, h1, "plan 1", summary_override="Branch_Point")
|
|
313
|
+
engine.visit(h1)
|
|
314
|
+
(ws / "a").touch()
|
|
315
|
+
h2a = engine.git_db.get_tree_hash()
|
|
316
|
+
engine.create_plan_node(h1, h2a, "plan 2a", summary_override="Branch_A")
|
|
317
|
+
engine.visit(h1)
|
|
318
|
+
(ws / "b").touch()
|
|
319
|
+
h2b = engine.git_db.get_tree_hash()
|
|
320
|
+
engine.create_plan_node(h1, h2b, "plan 2b", summary_override="Parent_Node")
|
|
321
|
+
engine.visit(h2b)
|
|
322
|
+
(ws / "c").touch()
|
|
323
|
+
h3 = engine.git_db.get_tree_hash()
|
|
324
|
+
engine.create_plan_node(h2b, h3, "plan 3", summary_override="Test_Target_Node")
|
|
325
|
+
engine.visit(h3)
|
|
326
|
+
(ws / "d").touch()
|
|
327
|
+
h4 = engine.git_db.get_tree_hash()
|
|
328
|
+
engine.create_plan_node(h3, h4, "plan 4", summary_override="Child_Node")
|
|
329
|
+
return engine
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def create_linear_history(engine: Engine) -> Tuple[Engine, Dict[str, str]]:
|
|
333
|
+
ws = engine.root_dir
|
|
334
|
+
|
|
335
|
+
# State A
|
|
336
|
+
(ws / "a.txt").write_text("A")
|
|
337
|
+
hash_a = engine.git_db.get_tree_hash()
|
|
338
|
+
engine.create_plan_node(EMPTY_TREE_HASH, hash_a, "Plan A", summary_override="State A")
|
|
339
|
+
|
|
340
|
+
# State B
|
|
341
|
+
(ws / "b.txt").write_text("B")
|
|
342
|
+
(ws / "a.txt").unlink()
|
|
343
|
+
hash_b = engine.git_db.get_tree_hash()
|
|
344
|
+
engine.create_plan_node(hash_a, hash_b, "Plan B", summary_override="State B")
|
|
345
|
+
|
|
346
|
+
hashes = {"a": hash_a, "b": hash_b}
|
|
347
|
+
return engine, hashes
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def create_dirty_workspace_history(engine: Engine) -> Tuple[Engine, str]:
|
|
351
|
+
work_dir = engine.root_dir
|
|
352
|
+
file_path = work_dir / "file.txt"
|
|
353
|
+
|
|
354
|
+
# State A
|
|
355
|
+
file_path.write_text("v1")
|
|
356
|
+
hash_a = engine.git_db.get_tree_hash()
|
|
357
|
+
engine.capture_drift(hash_a, message="State A")
|
|
358
|
+
|
|
359
|
+
# State B (HEAD)
|
|
360
|
+
file_path.write_text("v2")
|
|
361
|
+
engine.capture_drift(engine.git_db.get_tree_hash(), message="State B")
|
|
362
|
+
|
|
363
|
+
# Dirty State
|
|
364
|
+
file_path.write_text("v3")
|
|
365
|
+
|
|
366
|
+
return engine, hash_a
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def create_linear_history_from_specs(engine: Engine, specs: List[Dict[str, Any]]):
|
|
370
|
+
parent_hash = EMPTY_TREE_HASH
|
|
371
|
+
if engine.history_graph:
|
|
372
|
+
# If history is not empty, start from the latest node
|
|
373
|
+
latest_node = sorted(engine.history_graph.values(), key=lambda n: n.timestamp)[-1]
|
|
374
|
+
parent_hash = latest_node.output_tree
|
|
375
|
+
|
|
376
|
+
for i, spec in enumerate(specs):
|
|
377
|
+
# Create a unique file change for each node to ensure a new tree hash
|
|
378
|
+
(engine.root_dir / f"file_{time.time()}_{i}.txt").touch()
|
|
379
|
+
new_hash = engine.git_db.get_tree_hash()
|
|
380
|
+
|
|
381
|
+
if spec["type"] == "plan":
|
|
382
|
+
engine.create_plan_node(
|
|
383
|
+
input_tree=parent_hash,
|
|
384
|
+
output_tree=new_hash,
|
|
385
|
+
plan_content=spec.get("content", ""),
|
|
386
|
+
summary_override=spec["summary"],
|
|
387
|
+
)
|
|
388
|
+
elif spec["type"] == "capture":
|
|
389
|
+
engine.capture_drift(new_hash, message=spec["summary"])
|
|
390
|
+
|
|
391
|
+
parent_hash = new_hash
|
|
392
|
+
# Re-align to ensure the engine's internal graph is fully updated
|
|
393
|
+
engine.align()
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def create_query_branching_history(engine: Engine) -> Tuple[Engine, str]:
|
|
397
|
+
ws = engine.root_dir
|
|
398
|
+
# root -> A
|
|
399
|
+
(ws / "f_a").touch()
|
|
400
|
+
h_a = engine.git_db.get_tree_hash()
|
|
401
|
+
node_a = engine.capture_drift(h_a, "Node A")
|
|
402
|
+
|
|
403
|
+
# A -> B (This will become the main branch)
|
|
404
|
+
(ws / "f_b").touch()
|
|
405
|
+
h_b = engine.git_db.get_tree_hash()
|
|
406
|
+
engine.capture_drift(h_b, "Node B")
|
|
407
|
+
|
|
408
|
+
# Go back to A to create the branch
|
|
409
|
+
engine.visit(node_a.output_tree)
|
|
410
|
+
|
|
411
|
+
# A -> C
|
|
412
|
+
(ws / "f_c").touch()
|
|
413
|
+
engine.capture_drift(engine.git_db.get_tree_hash(), "Node C")
|
|
414
|
+
|
|
415
|
+
# Checkout back to B to set it as the current HEAD for the test
|
|
416
|
+
engine.visit(h_b)
|
|
417
|
+
engine.align()
|
|
418
|
+
return engine, h_b
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"InMemoryDB": |-
|
|
2
|
+
一个模拟 GitDB 接口的内存数据库,用于快速测试。
|
|
3
|
+
"InMemoryDB.get_tree_hash": |-
|
|
4
|
+
对当前 VFS 内容进行确定性哈希。
|
|
5
|
+
"InMemoryHistoryManager": |-
|
|
6
|
+
同时实现 Reader 和 Writer 接口的内存历史管理器。
|
|
7
|
+
"VirtualFileSystem": |-
|
|
8
|
+
一个简单的内存虚拟文件系统。
|
|
9
|
+
"create_branching_history": |-
|
|
10
|
+
Creates a common branching history for testing.
|
|
11
|
+
History:
|
|
12
|
+
- n0 (root) -> n1 -> n2 (branch point) -> n3a (branch A) -> n4 (summary)
|
|
13
|
+
\-> n3b (branch B)
|
|
14
|
+
"create_capture_node_with_change": |-
|
|
15
|
+
Creates a file change in the workspace and generates a new Capture node.
|
|
16
|
+
The new node is parented to the current HEAD of the engine.
|
|
17
|
+
Returns the output_tree hash of the new node.
|
|
18
|
+
"create_complex_link_history": |-
|
|
19
|
+
Creates a complex history to ensure a specific node has all navigation link types.
|
|
20
|
+
Node n3 will have: a parent (n2b), a child (n4), an ancestor branch point (n1),
|
|
21
|
+
and an ancestor summary node (n_summary).
|
|
22
|
+
"create_dirty_workspace_history": |-
|
|
23
|
+
Creates a history A -> B, then makes the workspace dirty.
|
|
24
|
+
- State A: file.txt -> "v1"
|
|
25
|
+
- State B (HEAD): file.txt -> "v2"
|
|
26
|
+
- Dirty State: file.txt -> "v3"
|
|
27
|
+
Returns the engine and the hash of state A for checkout tests.
|
|
28
|
+
"create_linear_history": |-
|
|
29
|
+
Creates a simple linear history A -> B.
|
|
30
|
+
- State A: a.txt
|
|
31
|
+
- State B: b.txt (a.txt is removed)
|
|
32
|
+
Returns the engine and a dictionary mapping state names ('a', 'b') to their output tree hashes.
|
|
33
|
+
"create_linear_history_from_specs": |-
|
|
34
|
+
Creates a linear history based on a list of specifications.
|
|
35
|
+
Each spec is a dict: {'type': 'plan'|'capture', 'summary': str, 'content': Optional[str]}
|
|
36
|
+
"create_node_via_cli": |-
|
|
37
|
+
Helper to create a node via the CLI runner and return its commit hash.
|
|
38
|
+
"create_plan_node_with_change": |-
|
|
39
|
+
Creates a file change in the workspace and generates a new Plan node.
|
|
40
|
+
Returns the output_tree hash of the new node.
|
|
41
|
+
"create_query_branching_history": |-
|
|
42
|
+
Creates a specific branching history for query reachability tests.
|
|
43
|
+
History: root -> A -> B (HEAD)
|
|
44
|
+
\-> C (unreachable)
|
|
45
|
+
Returns the engine and the hash of state B (the HEAD).
|
|
46
|
+
"get_local_quipu_heads": |-
|
|
47
|
+
Helper to get a set of all local quipu head commit hashes.
|
|
48
|
+
"run_git_command": |-
|
|
49
|
+
Helper to run a git command and return stdout.
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
{
|
|
2
|
+
"fingerprints": {
|
|
3
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#engine_instance": {
|
|
4
|
+
"baseline_code_signature_text": "def engine_instance(git_workspace: Path) -> Engine:",
|
|
5
|
+
"baseline_code_structure_hash": "508b467f12049f2a128a83de3b3bf26762a4f37b630e28c4eab7f4c34630d020",
|
|
6
|
+
"baseline_yaml_content_hash": "db9af6f9ab08827b717045437dfcef2083d7963fc22ccec3ebddb6b7c287f86c"
|
|
7
|
+
},
|
|
8
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#executor": {
|
|
9
|
+
"baseline_code_signature_text": "def executor(tmp_path: Path):",
|
|
10
|
+
"baseline_code_structure_hash": "828bede5f3d6f8a39a42fb146f9ac9e2121d63b156b32cbb46241212812b1942",
|
|
11
|
+
"baseline_yaml_content_hash": "45e3c92865ee2aa7de7efbaa80250df0f55de2ef095240af011945389b506487"
|
|
12
|
+
},
|
|
13
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#git_workspace": {
|
|
14
|
+
"baseline_code_signature_text": "def git_workspace(tmp_path: Path) -> Path:",
|
|
15
|
+
"baseline_code_structure_hash": "212c48cd2bfdcb11d1b5cfa9bb9aacd9a8b97a695863b62ebbfabbfdcc3c4ebf",
|
|
16
|
+
"baseline_yaml_content_hash": "9acade793a04a427d40fea92e189056736a0176ca744f8a80c4b317de861e9c2"
|
|
17
|
+
},
|
|
18
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#isolated_vault": {
|
|
19
|
+
"baseline_code_signature_text": "def isolated_vault(executor) -> Path:",
|
|
20
|
+
"baseline_code_structure_hash": "4266808927f59d2f83309312cbfbe27adce4d15f5be9898b63a4246c41dcff7c",
|
|
21
|
+
"baseline_yaml_content_hash": "4564ac7af7fe857ce674e09d77054ec16cea7177a5510422e3527500986e3794"
|
|
22
|
+
},
|
|
23
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#mock_engine": {
|
|
24
|
+
"baseline_code_signature_text": "def mock_engine():",
|
|
25
|
+
"baseline_code_structure_hash": "356e9fb160aafb3b3dff193494c8ec9808994d6794585f82c0f088c667dae738",
|
|
26
|
+
"baseline_yaml_content_hash": "d452e33e4d45988715261d1ac74d72568a97a3b58678054e3f2755330f988cd7"
|
|
27
|
+
},
|
|
28
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#mock_runtime": {
|
|
29
|
+
"baseline_code_signature_text": "def mock_runtime():",
|
|
30
|
+
"baseline_code_structure_hash": "33afd9208fd13d1928de8848342ed791bf13f87918ea571de8ad156a621eca13",
|
|
31
|
+
"baseline_yaml_content_hash": "328e7d4a0cdf5e44f753ec79e30ed151db691dc806ac7aea9368fc57e17d1f03"
|
|
32
|
+
},
|
|
33
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#mock_runtime_bus": {
|
|
34
|
+
"baseline_code_signature_text": "def mock_runtime_bus(monkeypatch):",
|
|
35
|
+
"baseline_code_structure_hash": "7cf21c2a06934f4c8699dfc2ede7d34009da427cb32a86b3c32fb864ef905462",
|
|
36
|
+
"baseline_yaml_content_hash": "b5df45efe6096cbcb714abce7bbc1622d6c9e15567e715875e23b646fcff972a"
|
|
37
|
+
},
|
|
38
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#quipu_workspace": {
|
|
39
|
+
"baseline_code_signature_text": "def quipu_workspace(engine_instance: Engine):",
|
|
40
|
+
"baseline_code_structure_hash": "802bd8d11b57f1ad06b0e92bb5f75d8cc3f2dc544f299177179d13f01bcaa448",
|
|
41
|
+
"baseline_yaml_content_hash": "a2b612e297794a1d66d50d7b24b1cbfc6c181647ce34ebdf95599f7b44e07101"
|
|
42
|
+
},
|
|
43
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#runner": {
|
|
44
|
+
"baseline_code_signature_text": "def runner() -> CliRunner:",
|
|
45
|
+
"baseline_code_structure_hash": "261ea21cb8282c88236db52b977b2618b009387fcd2317c1fdba9666e1ac4587",
|
|
46
|
+
"baseline_yaml_content_hash": "c494b687eac604601096a641a5bf66943175ad538f97595ae6c8e07b07bea26d"
|
|
47
|
+
},
|
|
48
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/fixtures.py#sync_test_environment": {
|
|
49
|
+
"baseline_code_signature_text": "def sync_test_environment(tmp_path_factory):",
|
|
50
|
+
"baseline_code_structure_hash": "24a3961ed104cd64fdc6f9bb10972cdb4da79c48651ffc5368c42b00134f6149",
|
|
51
|
+
"baseline_yaml_content_hash": "356e155289d0fda418d23a3f8fa386da6348b2f15a7e645b79c0c9c648634cc8"
|
|
52
|
+
},
|
|
53
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB": {
|
|
54
|
+
"baseline_code_signature_text": "class InMemoryDB:",
|
|
55
|
+
"baseline_code_structure_hash": "9e05bbd44314ebe643651d8910de5c0e60ec7232d4b08be981721d658f7f789f",
|
|
56
|
+
"baseline_yaml_content_hash": "11b2d1a19410e45345c134bbfb75a1b9c458f3d600d96d1013a483ca24d113d5"
|
|
57
|
+
},
|
|
58
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB.__init__": {
|
|
59
|
+
"baseline_code_signature_text": "def __init__(self):",
|
|
60
|
+
"baseline_code_structure_hash": "9bab2b1dd22fea04e58176b09f65ef4f673738c47abf25fca7e0c62af472206f"
|
|
61
|
+
},
|
|
62
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB.checkout_tree": {
|
|
63
|
+
"baseline_code_signature_text": "def checkout_tree(self, new_tree_hash: str, old_tree_hash: Optional[str] = None):",
|
|
64
|
+
"baseline_code_structure_hash": "5665baaadaf6a2b3e5f09812ec429cd57f9cd0ee96ec6a6fd9b574de0638f5a5"
|
|
65
|
+
},
|
|
66
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB.get_diff_name_status": {
|
|
67
|
+
"baseline_code_signature_text": "def get_diff_name_status(self, old_tree: str, new_tree: str) -> List[Tuple[str, str]]:",
|
|
68
|
+
"baseline_code_structure_hash": "807343877a65b864a254b3e3719d15a6cc0edb17c4e792ea1bba00c60f0be910"
|
|
69
|
+
},
|
|
70
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB.get_diff_stat": {
|
|
71
|
+
"baseline_code_signature_text": "def get_diff_stat(self, old_tree: str, new_tree: str) -> str:",
|
|
72
|
+
"baseline_code_structure_hash": "ce6f966e1089f6eb26f95e61986f232700fdcaf765f9b31111d9d7ebb473ea47"
|
|
73
|
+
},
|
|
74
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryDB.get_tree_hash": {
|
|
75
|
+
"baseline_code_signature_text": "def get_tree_hash(self) -> str:",
|
|
76
|
+
"baseline_code_structure_hash": "9fd88b05fd5c0e70ea2ea2a59b07ed091770257177751914385e56deeb306eff",
|
|
77
|
+
"baseline_yaml_content_hash": "59bf4c81e53df8a20316d26ec93e0d11c6a550264bf897046a8e3adfbbe2ab2b"
|
|
78
|
+
},
|
|
79
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager": {
|
|
80
|
+
"baseline_code_signature_text": "class InMemoryHistoryManager(HistoryReader, HistoryWriter):",
|
|
81
|
+
"baseline_code_structure_hash": "962a4a8935d136f0b54dc8726d0cc5217fa021b39711045bc87661df1602286f",
|
|
82
|
+
"baseline_yaml_content_hash": "258740eea91ab75bf94fa5ab1aed5ec584df07b6f9be4c583ea06499727330a3"
|
|
83
|
+
},
|
|
84
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.__init__": {
|
|
85
|
+
"baseline_code_signature_text": "def __init__(self, db: InMemoryDB):",
|
|
86
|
+
"baseline_code_structure_hash": "d83218c094372a8d28cf658577483ef46c9069b26b63410c35e75ace59ba0329"
|
|
87
|
+
},
|
|
88
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.create_node": {
|
|
89
|
+
"baseline_code_signature_text": "def create_node(self, node_type: str, input_tree: str, output_tree: str, content: str, summary_override: Optional[str] = None, **kwargs: Any = {}) -> QuipuNode:",
|
|
90
|
+
"baseline_code_structure_hash": "0b3e983f67b1351f7a4361e31a7c9144d1988621951d626bf72c09424a75d639"
|
|
91
|
+
},
|
|
92
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.find_nodes": {
|
|
93
|
+
"baseline_code_signature_text": "def find_nodes(self, summary_regex: Optional[str] = None, node_type: Optional[str] = None, limit: int = 10) -> List[QuipuNode]:",
|
|
94
|
+
"baseline_code_structure_hash": "3d04cb357877311ed8d37041f5ad5d0f322ed4105e52f5b88cfd40b6f110f6cc"
|
|
95
|
+
},
|
|
96
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_ancestor_output_trees": {
|
|
97
|
+
"baseline_code_signature_text": "def get_ancestor_output_trees(self, start_output_tree_hash: str) -> Set[str]:",
|
|
98
|
+
"baseline_code_structure_hash": "5ae091ca177977fc323d5563cb7f0c6e7af44ac50237f951d24c9793c2336220"
|
|
99
|
+
},
|
|
100
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_descendant_output_trees": {
|
|
101
|
+
"baseline_code_signature_text": "def get_descendant_output_trees(self, start_output_tree_hash: str) -> Set[str]:",
|
|
102
|
+
"baseline_code_structure_hash": "8eb09e56e11e9534720ef7286af9a75507b606322ada07811813f6b3278f5edd"
|
|
103
|
+
},
|
|
104
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_blobs": {
|
|
105
|
+
"baseline_code_signature_text": "def get_node_blobs(self, commit_hash: str) -> Dict[str, bytes]:",
|
|
106
|
+
"baseline_code_structure_hash": "48acf7a37a5612c09d5062797e966133a5c15ba17d05e10407be3235bb076f3d"
|
|
107
|
+
},
|
|
108
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_content": {
|
|
109
|
+
"baseline_code_signature_text": "def get_node_content(self, node: QuipuNode) -> str:",
|
|
110
|
+
"baseline_code_structure_hash": "72fb728d5fb5468b523a77045d87750229fb34202f36e0bfe8861de1ab999ed8"
|
|
111
|
+
},
|
|
112
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_count": {
|
|
113
|
+
"baseline_code_signature_text": "def get_node_count(self) -> int:",
|
|
114
|
+
"baseline_code_structure_hash": "f248a486494c998cc0f98482e50a5e3292f3132d247377d5088251762489517e"
|
|
115
|
+
},
|
|
116
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_position": {
|
|
117
|
+
"baseline_code_signature_text": "def get_node_position(self, output_tree_hash: str) -> int:",
|
|
118
|
+
"baseline_code_structure_hash": "eeb815e029cbffaf43c5365481a21a4251ca6fb30632886a63a5716104041b0e"
|
|
119
|
+
},
|
|
120
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.get_private_data": {
|
|
121
|
+
"baseline_code_signature_text": "def get_private_data(self, node_commit_hash: str) -> Optional[str]:",
|
|
122
|
+
"baseline_code_structure_hash": "b03c5152ce31de33095b38682a69df3dcfcd6551fd2d0e5109137fb9a8e6a772"
|
|
123
|
+
},
|
|
124
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.load_all_nodes": {
|
|
125
|
+
"baseline_code_signature_text": "def load_all_nodes(self) -> List[QuipuNode]:",
|
|
126
|
+
"baseline_code_structure_hash": "860f1b0ce953562bf9798d8e0e7a6d05c0aada817fc5e88689012cb45876f7be"
|
|
127
|
+
},
|
|
128
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#InMemoryHistoryManager.load_nodes_paginated": {
|
|
129
|
+
"baseline_code_signature_text": "def load_nodes_paginated(self, limit: int, offset: int) -> List[QuipuNode]:",
|
|
130
|
+
"baseline_code_structure_hash": "cf4d892bf90a00fa3f083ef8e4bb292b58bf36a417cf53e04002657744c0022e"
|
|
131
|
+
},
|
|
132
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#VirtualFileSystem": {
|
|
133
|
+
"baseline_code_signature_text": "class VirtualFileSystem:",
|
|
134
|
+
"baseline_code_structure_hash": "6bee4fef645ed9178324a9e0eb454ed5ebac015954e168eb51cba2553caaf325",
|
|
135
|
+
"baseline_yaml_content_hash": "c378a76357a9a1ccc65099769acf450a9accb6936ab4c5c3f6411092374d9609"
|
|
136
|
+
},
|
|
137
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#VirtualFileSystem.__init__": {
|
|
138
|
+
"baseline_code_signature_text": "def __init__(self):",
|
|
139
|
+
"baseline_code_structure_hash": "9bab2b1dd22fea04e58176b09f65ef4f673738c47abf25fca7e0c62af472206f"
|
|
140
|
+
},
|
|
141
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#VirtualFileSystem.copy": {
|
|
142
|
+
"baseline_code_signature_text": "def copy(self) -> VirtualFileSystem:",
|
|
143
|
+
"baseline_code_structure_hash": "568018bce5cb8d6b0a2a72c2f8d4dc40dfc67db2792096d93e525d1ff339d823"
|
|
144
|
+
},
|
|
145
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#VirtualFileSystem.read": {
|
|
146
|
+
"baseline_code_signature_text": "def read(self, path: str) -> Optional[str]:",
|
|
147
|
+
"baseline_code_structure_hash": "610c3197a70c8c4e0dc5ddd1a636a625ed5cda307bdbca93d0fb017850a06d1c"
|
|
148
|
+
},
|
|
149
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#VirtualFileSystem.write": {
|
|
150
|
+
"baseline_code_signature_text": "def write(self, path: str, content: str):",
|
|
151
|
+
"baseline_code_structure_hash": "50fd606d639eaaac881ea1fa5f2f2a97c4919d258818e279b911bc1f4d7031b3"
|
|
152
|
+
},
|
|
153
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_branching_history": {
|
|
154
|
+
"baseline_code_signature_text": "def create_branching_history(engine: Engine) -> Engine:",
|
|
155
|
+
"baseline_code_structure_hash": "df7ba659995fe344b131ba341c3e5941b1f2b7fae977485e0dd0d5ff9b7fa337",
|
|
156
|
+
"baseline_yaml_content_hash": "cf0e780d4c2f506aa8493a79c7785859dbe57be0ff0d391ec4ae016583a0d7bf"
|
|
157
|
+
},
|
|
158
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_capture_node_with_change": {
|
|
159
|
+
"baseline_code_signature_text": "def create_capture_node_with_change(engine: Engine, file_name: str, content: str, message: str) -> str:",
|
|
160
|
+
"baseline_code_structure_hash": "494564c8a001bce88c6cf3e5c16759210b0516459d7d4c23619b1130504d5401",
|
|
161
|
+
"baseline_yaml_content_hash": "352884bfbba30a002a2e79028f2abacfbd751ba35198cccde6104a75cb4e9350"
|
|
162
|
+
},
|
|
163
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_complex_link_history": {
|
|
164
|
+
"baseline_code_signature_text": "def create_complex_link_history(engine: Engine) -> Engine:",
|
|
165
|
+
"baseline_code_structure_hash": "9b3bf012779979584d371aa9e851f4880c5e330650aae5e1981bf4ed570fbf0d",
|
|
166
|
+
"baseline_yaml_content_hash": "2b18d49fe70c484ef9eb7e30b82ef7947626997888fc200007e9bc82bbb52049"
|
|
167
|
+
},
|
|
168
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_dirty_workspace_history": {
|
|
169
|
+
"baseline_code_signature_text": "def create_dirty_workspace_history(engine: Engine) -> Tuple[Engine, str]:",
|
|
170
|
+
"baseline_code_structure_hash": "9a1b473936bc06f3c7c301e66140295213df44abc420f8775246d5987b8c1cb0",
|
|
171
|
+
"baseline_yaml_content_hash": "788b7ec1efaaeb6e6b78fdfd2bdd37d2e351d623d9295291c369478832bb739d"
|
|
172
|
+
},
|
|
173
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_linear_history": {
|
|
174
|
+
"baseline_code_signature_text": "def create_linear_history(engine: Engine) -> Tuple[Engine, Dict[str, str]]:",
|
|
175
|
+
"baseline_code_structure_hash": "3ada516acb039d0433939843fde70504f99dee0302a1342292fc8d6c9fabf883",
|
|
176
|
+
"baseline_yaml_content_hash": "2b2e026a825ce169baf9da35d706d1e55fa1ca76af4b7605e78bcbc2e6383599"
|
|
177
|
+
},
|
|
178
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_linear_history_from_specs": {
|
|
179
|
+
"baseline_code_signature_text": "def create_linear_history_from_specs(engine: Engine, specs: List[Dict[str, Any]]):",
|
|
180
|
+
"baseline_code_structure_hash": "4e0464d5d219a29b0877daa0db5127754a0527bb0e2ce2b667521475b6913f19",
|
|
181
|
+
"baseline_yaml_content_hash": "c7ec7be674a17ad41caac42e79b2950813e70941b054b8b5f6b758a28b36722d"
|
|
182
|
+
},
|
|
183
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_node_via_cli": {
|
|
184
|
+
"baseline_code_signature_text": "def create_node_via_cli(runner: CliRunner, work_dir: Path, content: str) -> str:",
|
|
185
|
+
"baseline_code_structure_hash": "5d80af898918da29c7bf47de2fc50c82d26e55da1ed94e52cf8706bd7b84c9d8",
|
|
186
|
+
"baseline_yaml_content_hash": "e4aa9c4168e56c0a2f57abc6a79b10ac7853ab019b0c30b5582b0cc12dcf5577"
|
|
187
|
+
},
|
|
188
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_plan_node_with_change": {
|
|
189
|
+
"baseline_code_signature_text": "def create_plan_node_with_change(engine: Engine, parent_hash: str, file_name: str, content: str, message: str) -> str:",
|
|
190
|
+
"baseline_code_structure_hash": "cf61ae48f737c72cd80bbfb1fb68af0b154ff553270f31e181603b9445bc2022",
|
|
191
|
+
"baseline_yaml_content_hash": "8c2dc8174d13fa669d9125a57591161fa3153ad590205eeada686934077fbcb7"
|
|
192
|
+
},
|
|
193
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#create_query_branching_history": {
|
|
194
|
+
"baseline_code_signature_text": "def create_query_branching_history(engine: Engine) -> Tuple[Engine, str]:",
|
|
195
|
+
"baseline_code_structure_hash": "b5df830ed85fcd3b85c442eadaf3dfbe4ccc48a4f81f70f89bc0d94d02ea232e",
|
|
196
|
+
"baseline_yaml_content_hash": "2b33e55e9b1b15627669e69594fbb8287dac86b82599fb48aa339605fc480ac8"
|
|
197
|
+
},
|
|
198
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#get_local_quipu_heads": {
|
|
199
|
+
"baseline_code_signature_text": "def get_local_quipu_heads(work_dir: Path) -> set[str]:",
|
|
200
|
+
"baseline_code_structure_hash": "98f18e5a64b1643d42f06af5b609169f653f638e973dd802ce642250bd754793",
|
|
201
|
+
"baseline_yaml_content_hash": "568480bdd2b8aa9ef17a3754a68a6013415adf9bcf951544c00d593c28cfb1b6"
|
|
202
|
+
},
|
|
203
|
+
"py://packages/pyquipu-test-utils/src/quipu/test_utils/helpers.py#run_git_command": {
|
|
204
|
+
"baseline_code_signature_text": "def run_git_command(cwd: Path, args: list[str], check: bool = True) -> str:",
|
|
205
|
+
"baseline_code_structure_hash": "ab5208c68cb72aff451337e18f15003513c4e1c630a1f8604568417243f200d7",
|
|
206
|
+
"baseline_yaml_content_hash": "362d9c62b2f1936e5224993c2a2aad1fb3550f95a81f599d1f4d299e34b97b4c"
|
|
207
|
+
},
|
|
208
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#engine_instance": {
|
|
209
|
+
"baseline_code_signature_text": "def engine_instance(git_workspace: Path) -> Engine:",
|
|
210
|
+
"baseline_code_structure_hash": "508b467f12049f2a128a83de3b3bf26762a4f37b630e28c4eab7f4c34630d020",
|
|
211
|
+
"baseline_yaml_content_hash": "db9af6f9ab08827b717045437dfcef2083d7963fc22ccec3ebddb6b7c287f86c"
|
|
212
|
+
},
|
|
213
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#executor": {
|
|
214
|
+
"baseline_code_signature_text": "def executor(tmp_path: Path):",
|
|
215
|
+
"baseline_code_structure_hash": "828bede5f3d6f8a39a42fb146f9ac9e2121d63b156b32cbb46241212812b1942",
|
|
216
|
+
"baseline_yaml_content_hash": "45e3c92865ee2aa7de7efbaa80250df0f55de2ef095240af011945389b506487"
|
|
217
|
+
},
|
|
218
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#git_workspace": {
|
|
219
|
+
"baseline_code_signature_text": "def git_workspace(tmp_path: Path) -> Path:",
|
|
220
|
+
"baseline_code_structure_hash": "212c48cd2bfdcb11d1b5cfa9bb9aacd9a8b97a695863b62ebbfabbfdcc3c4ebf",
|
|
221
|
+
"baseline_yaml_content_hash": "9acade793a04a427d40fea92e189056736a0176ca744f8a80c4b317de861e9c2"
|
|
222
|
+
},
|
|
223
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#isolated_vault": {
|
|
224
|
+
"baseline_code_signature_text": "def isolated_vault(executor) -> Path:",
|
|
225
|
+
"baseline_code_structure_hash": "4266808927f59d2f83309312cbfbe27adce4d15f5be9898b63a4246c41dcff7c",
|
|
226
|
+
"baseline_yaml_content_hash": "4564ac7af7fe857ce674e09d77054ec16cea7177a5510422e3527500986e3794"
|
|
227
|
+
},
|
|
228
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#mock_engine": {
|
|
229
|
+
"baseline_code_signature_text": "def mock_engine():",
|
|
230
|
+
"baseline_code_structure_hash": "356e9fb160aafb3b3dff193494c8ec9808994d6794585f82c0f088c667dae738",
|
|
231
|
+
"baseline_yaml_content_hash": "d452e33e4d45988715261d1ac74d72568a97a3b58678054e3f2755330f988cd7"
|
|
232
|
+
},
|
|
233
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#mock_runtime": {
|
|
234
|
+
"baseline_code_signature_text": "def mock_runtime():",
|
|
235
|
+
"baseline_code_structure_hash": "33afd9208fd13d1928de8848342ed791bf13f87918ea571de8ad156a621eca13",
|
|
236
|
+
"baseline_yaml_content_hash": "328e7d4a0cdf5e44f753ec79e30ed151db691dc806ac7aea9368fc57e17d1f03"
|
|
237
|
+
},
|
|
238
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#mock_runtime_bus": {
|
|
239
|
+
"baseline_code_signature_text": "def mock_runtime_bus(monkeypatch):",
|
|
240
|
+
"baseline_code_structure_hash": "7cf21c2a06934f4c8699dfc2ede7d34009da427cb32a86b3c32fb864ef905462",
|
|
241
|
+
"baseline_yaml_content_hash": "b5df45efe6096cbcb714abce7bbc1622d6c9e15567e715875e23b646fcff972a"
|
|
242
|
+
},
|
|
243
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#quipu_workspace": {
|
|
244
|
+
"baseline_code_signature_text": "def quipu_workspace(engine_instance: Engine):",
|
|
245
|
+
"baseline_code_structure_hash": "802bd8d11b57f1ad06b0e92bb5f75d8cc3f2dc544f299177179d13f01bcaa448",
|
|
246
|
+
"baseline_yaml_content_hash": "a2b612e297794a1d66d50d7b24b1cbfc6c181647ce34ebdf95599f7b44e07101"
|
|
247
|
+
},
|
|
248
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#runner": {
|
|
249
|
+
"baseline_code_signature_text": "def runner() -> CliRunner:",
|
|
250
|
+
"baseline_code_structure_hash": "261ea21cb8282c88236db52b977b2618b009387fcd2317c1fdba9666e1ac4587",
|
|
251
|
+
"baseline_yaml_content_hash": "c494b687eac604601096a641a5bf66943175ad538f97595ae6c8e07b07bea26d"
|
|
252
|
+
},
|
|
253
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/fixtures.py#sync_test_environment": {
|
|
254
|
+
"baseline_code_signature_text": "def sync_test_environment(tmp_path_factory):",
|
|
255
|
+
"baseline_code_structure_hash": "24a3961ed104cd64fdc6f9bb10972cdb4da79c48651ffc5368c42b00134f6149",
|
|
256
|
+
"baseline_yaml_content_hash": "356e155289d0fda418d23a3f8fa386da6348b2f15a7e645b79c0c9c648634cc8"
|
|
257
|
+
},
|
|
258
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#EMPTY_TREE_HASH": {},
|
|
259
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB": {
|
|
260
|
+
"baseline_code_signature_text": "class InMemoryDB:",
|
|
261
|
+
"baseline_code_structure_hash": "9e05bbd44314ebe643651d8910de5c0e60ec7232d4b08be981721d658f7f789f",
|
|
262
|
+
"baseline_yaml_content_hash": "11b2d1a19410e45345c134bbfb75a1b9c458f3d600d96d1013a483ca24d113d5"
|
|
263
|
+
},
|
|
264
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.__init__": {
|
|
265
|
+
"baseline_code_signature_text": "def __init__(self):",
|
|
266
|
+
"baseline_code_structure_hash": "9bab2b1dd22fea04e58176b09f65ef4f673738c47abf25fca7e0c62af472206f"
|
|
267
|
+
},
|
|
268
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.checkout_tree": {
|
|
269
|
+
"baseline_code_signature_text": "def checkout_tree(self, new_tree_hash: str, old_tree_hash: Optional[str] = None):",
|
|
270
|
+
"baseline_code_structure_hash": "5665baaadaf6a2b3e5f09812ec429cd57f9cd0ee96ec6a6fd9b574de0638f5a5"
|
|
271
|
+
},
|
|
272
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.get_diff_name_status": {
|
|
273
|
+
"baseline_code_signature_text": "def get_diff_name_status(self, old_tree: str, new_tree: str) -> List[Tuple[str, str]]:",
|
|
274
|
+
"baseline_code_structure_hash": "807343877a65b864a254b3e3719d15a6cc0edb17c4e792ea1bba00c60f0be910"
|
|
275
|
+
},
|
|
276
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.get_diff_stat": {
|
|
277
|
+
"baseline_code_signature_text": "def get_diff_stat(self, old_tree: str, new_tree: str) -> str:",
|
|
278
|
+
"baseline_code_structure_hash": "ce6f966e1089f6eb26f95e61986f232700fdcaf765f9b31111d9d7ebb473ea47"
|
|
279
|
+
},
|
|
280
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.get_tree_hash": {
|
|
281
|
+
"baseline_code_signature_text": "def get_tree_hash(self) -> str:",
|
|
282
|
+
"baseline_code_structure_hash": "9fd88b05fd5c0e70ea2ea2a59b07ed091770257177751914385e56deeb306eff",
|
|
283
|
+
"baseline_yaml_content_hash": "59bf4c81e53df8a20316d26ec93e0d11c6a550264bf897046a8e3adfbbe2ab2b"
|
|
284
|
+
},
|
|
285
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.nodes": {},
|
|
286
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.snapshots": {},
|
|
287
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryDB.vfs": {},
|
|
288
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager": {
|
|
289
|
+
"baseline_code_signature_text": "class InMemoryHistoryManager(HistoryReader, HistoryWriter):",
|
|
290
|
+
"baseline_code_structure_hash": "962a4a8935d136f0b54dc8726d0cc5217fa021b39711045bc87661df1602286f",
|
|
291
|
+
"baseline_yaml_content_hash": "258740eea91ab75bf94fa5ab1aed5ec584df07b6f9be4c583ea06499727330a3"
|
|
292
|
+
},
|
|
293
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.__init__": {
|
|
294
|
+
"baseline_code_signature_text": "def __init__(self, db: InMemoryDB):",
|
|
295
|
+
"baseline_code_structure_hash": "d83218c094372a8d28cf658577483ef46c9069b26b63410c35e75ace59ba0329"
|
|
296
|
+
},
|
|
297
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.create_node": {
|
|
298
|
+
"baseline_code_signature_text": "def create_node(self, node_type: str, input_tree: str, output_tree: str, content: str, summary_override: Optional[str] = None, **kwargs: Any = {}) -> QuipuNode:",
|
|
299
|
+
"baseline_code_structure_hash": "0b3e983f67b1351f7a4361e31a7c9144d1988621951d626bf72c09424a75d639"
|
|
300
|
+
},
|
|
301
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.db": {},
|
|
302
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.find_nodes": {
|
|
303
|
+
"baseline_code_signature_text": "def find_nodes(self, summary_regex: Optional[str] = None, node_type: Optional[str] = None, limit: int = 10) -> List[QuipuNode]:",
|
|
304
|
+
"baseline_code_structure_hash": "3d04cb357877311ed8d37041f5ad5d0f322ed4105e52f5b88cfd40b6f110f6cc"
|
|
305
|
+
},
|
|
306
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_ancestor_output_trees": {
|
|
307
|
+
"baseline_code_signature_text": "def get_ancestor_output_trees(self, start_output_tree_hash: str) -> Set[str]:",
|
|
308
|
+
"baseline_code_structure_hash": "5ae091ca177977fc323d5563cb7f0c6e7af44ac50237f951d24c9793c2336220"
|
|
309
|
+
},
|
|
310
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_descendant_output_trees": {
|
|
311
|
+
"baseline_code_signature_text": "def get_descendant_output_trees(self, start_output_tree_hash: str) -> Set[str]:",
|
|
312
|
+
"baseline_code_structure_hash": "8eb09e56e11e9534720ef7286af9a75507b606322ada07811813f6b3278f5edd"
|
|
313
|
+
},
|
|
314
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_blobs": {
|
|
315
|
+
"baseline_code_signature_text": "def get_node_blobs(self, commit_hash: str) -> Dict[str, bytes]:",
|
|
316
|
+
"baseline_code_structure_hash": "48acf7a37a5612c09d5062797e966133a5c15ba17d05e10407be3235bb076f3d"
|
|
317
|
+
},
|
|
318
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_content": {
|
|
319
|
+
"baseline_code_signature_text": "def get_node_content(self, node: QuipuNode) -> str:",
|
|
320
|
+
"baseline_code_structure_hash": "72fb728d5fb5468b523a77045d87750229fb34202f36e0bfe8861de1ab999ed8"
|
|
321
|
+
},
|
|
322
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_count": {
|
|
323
|
+
"baseline_code_signature_text": "def get_node_count(self) -> int:",
|
|
324
|
+
"baseline_code_structure_hash": "f248a486494c998cc0f98482e50a5e3292f3132d247377d5088251762489517e"
|
|
325
|
+
},
|
|
326
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_node_position": {
|
|
327
|
+
"baseline_code_signature_text": "def get_node_position(self, output_tree_hash: str) -> int:",
|
|
328
|
+
"baseline_code_structure_hash": "eeb815e029cbffaf43c5365481a21a4251ca6fb30632886a63a5716104041b0e"
|
|
329
|
+
},
|
|
330
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.get_private_data": {
|
|
331
|
+
"baseline_code_signature_text": "def get_private_data(self, node_commit_hash: str) -> Optional[str]:",
|
|
332
|
+
"baseline_code_structure_hash": "b03c5152ce31de33095b38682a69df3dcfcd6551fd2d0e5109137fb9a8e6a772"
|
|
333
|
+
},
|
|
334
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.load_all_nodes": {
|
|
335
|
+
"baseline_code_signature_text": "def load_all_nodes(self) -> List[QuipuNode]:",
|
|
336
|
+
"baseline_code_structure_hash": "860f1b0ce953562bf9798d8e0e7a6d05c0aada817fc5e88689012cb45876f7be"
|
|
337
|
+
},
|
|
338
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#InMemoryHistoryManager.load_nodes_paginated": {
|
|
339
|
+
"baseline_code_signature_text": "def load_nodes_paginated(self, limit: int, offset: int) -> List[QuipuNode]:",
|
|
340
|
+
"baseline_code_structure_hash": "cf4d892bf90a00fa3f083ef8e4bb292b58bf36a417cf53e04002657744c0022e"
|
|
341
|
+
},
|
|
342
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem": {
|
|
343
|
+
"baseline_code_signature_text": "class VirtualFileSystem:",
|
|
344
|
+
"baseline_code_structure_hash": "6bee4fef645ed9178324a9e0eb454ed5ebac015954e168eb51cba2553caaf325",
|
|
345
|
+
"baseline_yaml_content_hash": "c378a76357a9a1ccc65099769acf450a9accb6936ab4c5c3f6411092374d9609"
|
|
346
|
+
},
|
|
347
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem.__init__": {
|
|
348
|
+
"baseline_code_signature_text": "def __init__(self):",
|
|
349
|
+
"baseline_code_structure_hash": "9bab2b1dd22fea04e58176b09f65ef4f673738c47abf25fca7e0c62af472206f"
|
|
350
|
+
},
|
|
351
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem._files": {},
|
|
352
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem.copy": {
|
|
353
|
+
"baseline_code_signature_text": "def copy(self) -> VirtualFileSystem:",
|
|
354
|
+
"baseline_code_structure_hash": "568018bce5cb8d6b0a2a72c2f8d4dc40dfc67db2792096d93e525d1ff339d823"
|
|
355
|
+
},
|
|
356
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem.files": {},
|
|
357
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem.read": {
|
|
358
|
+
"baseline_code_signature_text": "def read(self, path: str) -> Optional[str]:",
|
|
359
|
+
"baseline_code_structure_hash": "610c3197a70c8c4e0dc5ddd1a636a625ed5cda307bdbca93d0fb017850a06d1c"
|
|
360
|
+
},
|
|
361
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#VirtualFileSystem.write": {
|
|
362
|
+
"baseline_code_signature_text": "def write(self, path: str, content: str):",
|
|
363
|
+
"baseline_code_structure_hash": "50fd606d639eaaac881ea1fa5f2f2a97c4919d258818e279b911bc1f4d7031b3"
|
|
364
|
+
},
|
|
365
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_branching_history": {
|
|
366
|
+
"baseline_code_signature_text": "def create_branching_history(engine: Engine) -> Engine:",
|
|
367
|
+
"baseline_code_structure_hash": "df7ba659995fe344b131ba341c3e5941b1f2b7fae977485e0dd0d5ff9b7fa337",
|
|
368
|
+
"baseline_yaml_content_hash": "cf0e780d4c2f506aa8493a79c7785859dbe57be0ff0d391ec4ae016583a0d7bf"
|
|
369
|
+
},
|
|
370
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_capture_node_with_change": {
|
|
371
|
+
"baseline_code_signature_text": "def create_capture_node_with_change(engine: Engine, file_name: str, content: str, message: str) -> str:",
|
|
372
|
+
"baseline_code_structure_hash": "494564c8a001bce88c6cf3e5c16759210b0516459d7d4c23619b1130504d5401",
|
|
373
|
+
"baseline_yaml_content_hash": "352884bfbba30a002a2e79028f2abacfbd751ba35198cccde6104a75cb4e9350"
|
|
374
|
+
},
|
|
375
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_complex_link_history": {
|
|
376
|
+
"baseline_code_signature_text": "def create_complex_link_history(engine: Engine) -> Engine:",
|
|
377
|
+
"baseline_code_structure_hash": "9b3bf012779979584d371aa9e851f4880c5e330650aae5e1981bf4ed570fbf0d",
|
|
378
|
+
"baseline_yaml_content_hash": "2b18d49fe70c484ef9eb7e30b82ef7947626997888fc200007e9bc82bbb52049"
|
|
379
|
+
},
|
|
380
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_dirty_workspace_history": {
|
|
381
|
+
"baseline_code_signature_text": "def create_dirty_workspace_history(engine: Engine) -> Tuple[Engine, str]:",
|
|
382
|
+
"baseline_code_structure_hash": "9a1b473936bc06f3c7c301e66140295213df44abc420f8775246d5987b8c1cb0",
|
|
383
|
+
"baseline_yaml_content_hash": "788b7ec1efaaeb6e6b78fdfd2bdd37d2e351d623d9295291c369478832bb739d"
|
|
384
|
+
},
|
|
385
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_linear_history": {
|
|
386
|
+
"baseline_code_signature_text": "def create_linear_history(engine: Engine) -> Tuple[Engine, Dict[str, str]]:",
|
|
387
|
+
"baseline_code_structure_hash": "3ada516acb039d0433939843fde70504f99dee0302a1342292fc8d6c9fabf883",
|
|
388
|
+
"baseline_yaml_content_hash": "2b2e026a825ce169baf9da35d706d1e55fa1ca76af4b7605e78bcbc2e6383599"
|
|
389
|
+
},
|
|
390
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_linear_history_from_specs": {
|
|
391
|
+
"baseline_code_signature_text": "def create_linear_history_from_specs(engine: Engine, specs: List[Dict[str, Any]]):",
|
|
392
|
+
"baseline_code_structure_hash": "4e0464d5d219a29b0877daa0db5127754a0527bb0e2ce2b667521475b6913f19",
|
|
393
|
+
"baseline_yaml_content_hash": "c7ec7be674a17ad41caac42e79b2950813e70941b054b8b5f6b758a28b36722d"
|
|
394
|
+
},
|
|
395
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_node_via_cli": {
|
|
396
|
+
"baseline_code_signature_text": "def create_node_via_cli(runner: CliRunner, work_dir: Path, content: str) -> str:",
|
|
397
|
+
"baseline_code_structure_hash": "5d80af898918da29c7bf47de2fc50c82d26e55da1ed94e52cf8706bd7b84c9d8",
|
|
398
|
+
"baseline_yaml_content_hash": "e4aa9c4168e56c0a2f57abc6a79b10ac7853ab019b0c30b5582b0cc12dcf5577"
|
|
399
|
+
},
|
|
400
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_plan_node_with_change": {
|
|
401
|
+
"baseline_code_signature_text": "def create_plan_node_with_change(engine: Engine, parent_hash: str, file_name: str, content: str, message: str) -> str:",
|
|
402
|
+
"baseline_code_structure_hash": "cf61ae48f737c72cd80bbfb1fb68af0b154ff553270f31e181603b9445bc2022",
|
|
403
|
+
"baseline_yaml_content_hash": "8c2dc8174d13fa669d9125a57591161fa3153ad590205eeada686934077fbcb7"
|
|
404
|
+
},
|
|
405
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#create_query_branching_history": {
|
|
406
|
+
"baseline_code_signature_text": "def create_query_branching_history(engine: Engine) -> Tuple[Engine, str]:",
|
|
407
|
+
"baseline_code_structure_hash": "b5df830ed85fcd3b85c442eadaf3dfbe4ccc48a4f81f70f89bc0d94d02ea232e",
|
|
408
|
+
"baseline_yaml_content_hash": "2b33e55e9b1b15627669e69594fbb8287dac86b82599fb48aa339605fc480ac8"
|
|
409
|
+
},
|
|
410
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#get_local_quipu_heads": {
|
|
411
|
+
"baseline_code_signature_text": "def get_local_quipu_heads(work_dir: Path) -> set[str]:",
|
|
412
|
+
"baseline_code_structure_hash": "98f18e5a64b1643d42f06af5b609169f653f638e973dd802ce642250bd754793",
|
|
413
|
+
"baseline_yaml_content_hash": "568480bdd2b8aa9ef17a3754a68a6013415adf9bcf951544c00d593c28cfb1b6"
|
|
414
|
+
},
|
|
415
|
+
"py://packages/quipu-test-utils/src/pyquipu/test_utils/helpers.py#run_git_command": {
|
|
416
|
+
"baseline_code_signature_text": "def run_git_command(cwd: Path, args: list[str], check: bool = True) -> str:",
|
|
417
|
+
"baseline_code_structure_hash": "ab5208c68cb72aff451337e18f15003513c4e1c630a1f8604568417243f200d7",
|
|
418
|
+
"baseline_yaml_content_hash": "362d9c62b2f1936e5224993c2a2aad1fb3550f95a81f599d1f4d299e34b97b4c"
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
"version": "1.0"
|
|
422
|
+
}
|