Files
Jarvis/packages/Memory/Tests/MemoryTests/SessionHistoryTests.swift
james.maesandClaude Opus 4.7 f9cd25d66e chore(test-naming): converge on Mock/Fake/Stub convention; document in CLAUDE.md; rename worst-mismatch stragglers
Per audit-2026-05-04 P2-15: 26 Mock*, 21 Fake*, 12 Stub* across the test
corpus, often used interchangeably for the same role. New CLAUDE.md
section "Test naming conventions" (line 127) sets the rule:

- Mock*: records calls AND returns scripted responses (assertion driver).
- Stub*: returns canned data without recording (deterministic input).
- Fake*: alternative implementation with realistic behavior (in-memory
  state-holder).

Renamed 15 worst-mismatch stragglers in the older corpus (per audit
constraint, did NOT touch types added in today's P1+P2 fix commits):

Stub* → Mock* (records + scripts):
- HybridSearchTests:    StubEmbedder → MockEmbedder
- HybridSearchTests:    StubStore → MockStore
- SessionHistoryTests:  StubStore → MockStore
- InProcessMemoryToolsTests: StubHybrid → MockHybrid
- InProcessMemoryToolsTests: StubHistory → MockHistory
- InProcessMemoryToolsTests: StubForget → MockForget

Mock* → Stub* (canned data, no recording):
- STTBackendSwitchTests: MockSpeechAnalyzerBridge → StubSpeechAnalyzerBridge
- STTBackendSwitchTests: MockWhisperKitBridge → StubWhisperKitBridge
- VoiceWiringTests:      MockVADEngineForW4 → StubVADEngineForW4
- VoiceWiringTests:      MockSTTProviderForW4 → StubSTTProviderForW4
- VoiceWiringTests:      MockTTSForW4 → StubTTSForW4
- VoiceWiringTests:      MockOrchestratorForW4 → StubOrchestratorForW4
- VoiceWiringTests:      MockBannerForW4 → StubBannerForW4
- VoiceWiringTests:      MockBusForW4 → StubBusForW4

Fake* → Mock* (records + scripts):
- WebviewBridgeOutboundTests:        FakeJSEvaluator → MockJSEvaluator
- HudStateCoordinatorBusWiringTests: FakeJSEvaluator → MockJSEvaluator
  (the comment on the type already said "Records each call for assertion")

Skipped per audit constraint:
- StubCapture/StubSink (Vision FrameAttachConfirmSendWiringTests, P1+P2)
- MockVADEngine + MockOrchestratorForController siblings (Voice
  VoiceControllerTests/VADGatedSessionTests, today's track-B churn)

Tests pass: Voice 87+23, MCP 85, Memory 88, Bus 58, AgentCore 19+72,
Vision 19, Shell 7+5. App target builds clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 16:42:16 -05:00

56 lines
1.9 KiB
Swift

import XCTest
@testable import Memory
/// Plan 07-03 Task 2 — SessionHistory unit tests with mock store.
final class SessionHistoryTests: XCTestCase {
actor MockStore: SessionHistoryReading {
var capturedSessionId: String?
var capturedLimit: Int?
var rowsToReturn: [TurnRow] = []
func recentTurnsForSession(sessionId: String, limit: Int) async throws -> [TurnRow] {
capturedSessionId = sessionId
capturedLimit = limit
return rowsToReturn
}
func setRows(_ rows: [TurnRow]) { rowsToReturn = rows }
}
private func makeRow(id: Int64, sessionId: String, createdAt: Int64) -> TurnRow {
TurnRow(id: id, sessionId: sessionId, role: "user", content: "hi",
source: "userText", createdAt: createdAt)
}
func testRecentTurnsPassesSessionAndLimit() async throws {
let store = MockStore()
await store.setRows([])
let hist = SessionHistory(store: store)
_ = try await hist.recentTurns(sessionId: "A", limit: 7)
let sid = await store.capturedSessionId
let lim = await store.capturedLimit
XCTAssertEqual(sid, "A")
XCTAssertEqual(lim, 7)
}
func testRecentTurnsCapsLimit() async throws {
let store = MockStore()
await store.setRows([])
let hist = SessionHistory(store: store)
_ = try await hist.recentTurns(sessionId: "A", limit: 100_000)
let lim = await store.capturedLimit
XCTAssertEqual(lim, 500)
}
func testRecentTurnsReturnsRowsAsIs() async throws {
let store = MockStore()
let row = makeRow(id: 1, sessionId: "A", createdAt: 5)
await store.setRows([row])
let hist = SessionHistory(store: store)
let rows = try await hist.recentTurns(sessionId: "A", limit: 50)
XCTAssertEqual(rows.count, 1)
XCTAssertEqual(rows[0], row)
}
}