gabriel / musehub public
test_phase3_gravity_provider.py python
116 lines 5.0 KB
Raw
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 9 days ago
1 """TDD spec for Phase 3, Part 2 — GravityProvider (issue #9).
2
3 New provider class ``GravityProvider`` with job type ``intel.code.gravity``.
4
5 Runs ``muse -C <repo_root> code gravity --json`` on push and upserts
6 the 6 gravity columns (gravity_pct, gravity_direct_dependents, gravity_transitive_dependents,
7 gravity_max_depth, gravity_depth_distribution, symbol_kind) into musehub_symbol_intel.
8
9 Key constraint: gravity upsert must NOT touch churn/blast columns.
10
11 Layers:
12 1. Registry — "intel.code.gravity" in _PROVIDER_REGISTRY
13 2. Protocol — provider instance satisfies IntelProvider
14 3. Dispatch — job_types_for_push("code") includes "intel.code.gravity"
15 4. Write — upserts all 6 gravity columns from muse output
16 5. Preserve — churn/blast untouched after gravity upsert
17 6. JSONB — depth_dist stored as dict, not string
18 7. Idempotent — run twice, one row with latest data
19 8. Multi-row — multiple symbols all upserted in one compute() call
20 9. Empty — empty symbols list returns [] gracefully
21 10. Error — non-zero subprocess exit returns [] gracefully
22 """
23 from __future__ import annotations
24
25 import json
26 import secrets
27 from unittest.mock import AsyncMock, patch
28
29 import pytest
30 from sqlalchemy import select
31 from sqlalchemy.ext.asyncio import AsyncSession
32
33 from muse.core.types import fake_id
34 from tests.factories import create_repo
35
36
37 def _uid() -> str:
38 return fake_id(secrets.token_hex(16))
39
40
41 def _mock_process(stdout: str, returncode: int = 0) -> AsyncMock:
42 proc = AsyncMock()
43 proc.returncode = returncode
44 proc.communicate = AsyncMock(return_value=(stdout.encode(), b""))
45 return proc
46
47
48 _GRAVITY_OUTPUT = json.dumps({
49 "total_production_symbols": 1883,
50 "max_depth": 9,
51 "symbols": [
52 {
53 "address": "musehub/storage/backends.py::S3Backend._key",
54 "name": "_key",
55 "kind": "method",
56 "file": "musehub/storage/backends.py",
57 "gravity_pct": 38.9,
58 "direct_dependents": 11,
59 "transitive_dependents": 733,
60 "max_depth": 6,
61 "depth_distribution": {"1": 11, "2": 484, "3": 197, "4": 35, "5": 5, "6": 1},
62 },
63 {
64 "address": "musehub/storage/backends.py::StorageBackend.get",
65 "name": "get",
66 "kind": "async_method",
67 "file": "musehub/storage/backends.py",
68 "gravity_pct": 36.2,
69 "direct_dependents": 424,
70 "transitive_dependents": 682,
71 "max_depth": 5,
72 "depth_distribution": {"1": 424, "2": 206, "3": 46, "4": 5, "5": 1},
73 },
74 ],
75 })
76
77
78 # ─────────────────────────────────────────────────────────────────────────────
79 # Layer 1 — Registry
80 # ─────────────────────────────────────────────────────────────────────────────
81
82 class TestGravityProviderRegistry:
83
84 def test_P3_29_gravity_in_provider_registry(self) -> None:
85 from musehub.services.musehub_intel_providers import _PROVIDER_REGISTRY
86 assert "intel.code.gravity" in _PROVIDER_REGISTRY, (
87 "intel.code.gravity not registered in _PROVIDER_REGISTRY"
88 )
89
90 def test_P3_30_gravity_satisfies_intel_provider_protocol(self) -> None:
91 from musehub.services.musehub_intel_providers import _PROVIDER_REGISTRY, IntelProvider
92 provider = _PROVIDER_REGISTRY["intel.code.gravity"]
93 assert isinstance(provider, IntelProvider)
94
95
96 # ─────────────────────────────────────────────────────────────────────────────
97 # Layer 2 — Dispatch
98 # ─────────────────────────────────────────────────────────────────────────────
99
100 class TestGravityProviderDispatch:
101
102 def test_P3_31_job_types_for_push_code_includes_gravity(self) -> None:
103 from musehub.services.musehub_intel_providers import job_types_for_push
104 types = job_types_for_push("code")
105 assert "intel.code.gravity" in types
106
107 def test_P3_32_job_types_for_push_midi_excludes_gravity(self) -> None:
108 from musehub.services.musehub_intel_providers import job_types_for_push
109 assert "intel.code.gravity" not in job_types_for_push("midi")
110
111 def test_P3_33_job_types_for_push_legacy_types_intact(self) -> None:
112 from musehub.services.musehub_intel_providers import job_types_for_push
113 types = job_types_for_push("code")
114 for required in ("intel.structural", "intel.code", "gc"):
115 assert required in types, f"{required} missing from job_types_for_push('code')"
116
File History 13 commits
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 9 days ago
sha256:408916fc5973ba59c6e4eebaa80ebdcc801c0a63205651e25009d11548f79454 chore: bump version to 0.2.0.dev2 — nightly.2, matching muse Sonnet 4.6 patch 12 days ago
sha256:d035733f21ccff27735fddebfbbe0ed24565a32a22db8de5885402262671ecd2 chore: bump version to 0.2.0rc15 for musehub#113 fix release Sonnet 4.6 patch 15 days ago
sha256:0032d6cfa33bc3c8367436ad768e7dd0e339b4332153160247da8266cb5fa352 Merge branch 'task/version-tags-phase3-server' into dev Human 17 days ago
sha256:4669620efda9ff41c55bdefd1f7bfe1c239d468428744c84ead9957e5a003a53 merge: rescue snapshot-recovery hardening (c00aa21d) into d… Opus 4.8 minor 30 days ago
sha256:a59da49c4611b970fc4b6ae48678ce4943261c213a07ddbd73ce9201df869b4a fix: remove false-positive proposal_comments index drop fro… Sonnet 4.6 patch 34 days ago
sha256:0a240d6dbff234f07d98a28a4a9a68db702f3f9ff9260196f24219bdb1c0b6f3 feat: render markdown mists as HTML with heading anchor links Sonnet 4.6 patch 34 days ago
sha256:24a7d47486ebc4ebd1832830580e177ec6f877b48dced8c000e198cdec4ce9d6 Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 36 days ago
sha256:b9ff931d147e0114a1f17060f415b89ed551c170a91ff226c70437aa5c85f9ee Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 36 days ago
sha256:d1122d21e73471879b460037b22c0b50fded7c423444a176f248428f75dac39c Merge 'task/fix-issue-pagination-cursor' into 'dev' — propo… Human 36 days ago
sha256:01e18975e73d2b3cd5b6db7929c895bef9aa6e0d4391dc5b2adfc548b41318dd Merge 'feat/adding-debug-logs-to-staging' into 'dev' — prop… Human 36 days ago
sha256:6b1949fc2797ca4c1936a637a4cbfec828ef56cf52398a2e74ca3c4f494e728f fix: use wire_bytes not mpack_bytes_raw in compute_object_b… Sonnet 4.6 patch 48 days ago
sha256:b99f2455dc346966d040133f5203297e6e3ef5803a93728a2c30568d0a0f7583 rename: delta_add → delta_upsert across wire format, models… Sonnet 4.6 patch 50 days ago