import XCTest @testable import LChatCore // 🤖 The perf ledger's pure halves: JSONL parsing (lenient — a torn line from // a crash mid-append must never sink the export), the Settings summary line // (pluralisation is a shipping requirement), and the export's diagnostic // byte cap. final class PerfTests: XCTestCase { func testEventRoundtripAndLenientParse() throws { let event = PerfEvent(t: 1_753_000_000_000, kind: "slow", name: "feed.openThread", ms: 1812.5, detail: "214 messages") let line = String(data: try JSONEncoder().encode(event), encoding: .utf8)! let jsonl = line + "\n{\"torn\":tru\n" + line + "\nnot json at all\n" let parsed = PerfEvent.parse(jsonl: jsonl) XCTAssertEqual(parsed, [event, event]) } func testSummaryEmpty() { XCTAssertNil(PerfEvent.summary([])) // Boot/metric/note events alone aren't "cuts" — nothing to say. XCTAssertNil(PerfEvent.summary([PerfEvent(t: 0, kind: "boot", name: "boot.firstFrame", ms: 500)])) } func testSummarySingularAndPlural() { let oneEach = [ PerfEvent(t: 0, kind: "hang", name: "main.hang", ms: 900), PerfEvent(t: 1, kind: "slow", name: "api.get", ms: 1500), ] XCTAssertEqual(PerfEvent.summary(oneEach), "1 hang · 1 slow moment · worst api.get 1.5s") let several = [ PerfEvent(t: 0, kind: "hang", name: "main.hang", ms: 900), PerfEvent(t: 1, kind: "hang", name: "main.hang", ms: 450), PerfEvent(t: 2, kind: "slow", name: "api.get", ms: 1500), PerfEvent(t: 3, kind: "slow", name: "feed.openThread", ms: 2400), ] XCTAssertEqual(PerfEvent.summary(several), "2 hangs · 2 slow moments · worst feed.openThread 2.4s") } func testSummaryHangsOnly() { let hangs = [PerfEvent(t: 0, kind: "hang", name: "main.hang", ms: 600)] XCTAssertEqual(PerfEvent.summary(hangs), "1 hang") } func testSummaryIncludesHitches() { let one = [PerfEvent(t: 0, kind: "hitch", name: "frame.hitch", ms: 180)] XCTAssertEqual(PerfEvent.summary(one), "1 hitch") let mixed = [ PerfEvent(t: 0, kind: "hang", name: "main.hang", ms: 600), PerfEvent(t: 1, kind: "hitch", name: "frame.hitch", ms: 180), PerfEvent(t: 2, kind: "hitch", name: "frame.hitch", ms: 250), ] XCTAssertEqual(PerfEvent.summary(mixed), "1 hang · 2 hitches") } func testCapDiagnosticsKeepsNewestUnderBudget() { let a = String(repeating: "a", count: 100) let b = String(repeating: "b", count: 100) let c = String(repeating: "c", count: 100) // Newest first in, newest kept: the cap stops at the first payload // that would overflow, never skipping ahead to a smaller older one. XCTAssertEqual(PerfExport.capDiagnostics([a, b, c], maxBytes: 250), [a, b]) XCTAssertEqual(PerfExport.capDiagnostics([a, b, c], maxBytes: 1000), [a, b, c]) XCTAssertEqual(PerfExport.capDiagnostics([a], maxBytes: 50), []) XCTAssertEqual(PerfExport.capDiagnostics([], maxBytes: 1000), []) } }