Files
Jarvis/packages/Memory/Tests/MemoryTests/MemoryQueriesAndModelTests.swift
james.maes a04a018785 test(07-03): add failing memory-read primitives + grep gate tests
- MemoryQueriesAndModelTests: hybrid SQL shape, FactRef/TurnRow Codable,
  ReplayEvent.memoryRetrieval kind round-trip
- SingleEmissionSiteGrepTests: testMemoryRetrievalHasSingleEmissionSite
  symmetric to the 07-02 memoryMutation gate

RED gate: tests reference MemoryQueries, FactRef.score/triggerTurnId,
TurnRow, ReplayEvent.memoryRetrieval — none of which exist yet.
2026-04-29 16:53:18 -05:00

64 lines
2.5 KiB
Swift

import XCTest
import Replay
@testable import Memory
/// Plan 07-03 Task 1 — unit tests for the new SQL constants and value types.
///
/// These tests do NOT touch SQLite. They exercise the static SQL strings,
/// the Codable conformance for FactRef and TurnRow, and the
/// ReplayEvent.memoryRetrieval round-trip.
final class MemoryQueriesAndModelTests: XCTestCase {
func testHybridSearchSQLContainsRRFExpression() {
let sql = MemoryQueries.hybridSearchSQL(k: 50)
XCTAssertTrue(sql.contains("SUM(1.0/(60+rank))"),
"RRF expression must use rrfK=60")
XCTAssertTrue(sql.contains("f.valid_to IS NULL AND f.forgotten_at IS NULL"))
XCTAssertTrue(sql.contains("AND k = 50"),
"vec0 cohort must template k as a literal (RESEARCH P9)")
XCTAssertTrue(sql.contains("bm25(facts_fts)"))
XCTAssertTrue(sql.contains("embedding MATCH"))
XCTAssertTrue(sql.contains("ORDER BY fused.rrf DESC"))
}
func testHybridSearchSQLRRFKConstant() {
XCTAssertEqual(MemoryQueries.rrfK, 60)
}
func testHybridSearchSQLHasNoSessionIdPredicate() {
let sql = MemoryQueries.hybridSearchSQL(k: 10)
XCTAssertFalse(sql.contains("session_id"),
"D-07 invariant: search_memory must be unscoped.")
}
func testForgetFactSQLUsesUpdateNotDelete() {
let sql = MemoryQueries.forgetFactSQL
XCTAssertTrue(sql.contains("UPDATE facts"))
XCTAssertFalse(sql.contains("DELETE FROM facts"))
}
func testFactRefIsCodable() throws {
let ref = FactRef(factId: 42, summary: "S P O", score: 0.5,
triggerTurnId: 7, timestamp: 1000)
let encoded = try JSONEncoder().encode(ref)
let decoded = try JSONDecoder().decode(FactRef.self, from: encoded)
XCTAssertEqual(decoded, ref)
}
func testTurnRowIsCodable() throws {
let row = TurnRow(id: 1, sessionId: "A", role: "user",
content: "hi", source: "userText", createdAt: 100)
let encoded = try JSONEncoder().encode(row)
let decoded = try JSONDecoder().decode(TurnRow.self, from: encoded)
XCTAssertEqual(decoded, row)
}
func testReplayEventMemoryRetrievalRoundtrip() {
let bytes = "{\"factId\":1}".data(using: .utf8)!
let ev: ReplayEvent = .memoryRetrieval(bytes)
let (kind, payload) = ev.encoded()
XCTAssertEqual(kind, "memory_retrieval")
XCTAssertEqual(payload, bytes)
}
}