From 745eefe0bed9ac2c4c3e60114c125952ad06a40b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 14 Dec 2025 03:06:12 +0000 Subject: [PATCH] test(macos): cover settings + activity models --- .../ClawdisIPCTests/CronModelsTests.swift | 19 +++++- .../ClawdisIPCTests/SessionDataTests.swift | 44 ++++++++++++ .../SettingsViewSmokeTests.swift | 53 ++++++++++++++- .../WorkActivityStoreTests.swift | 68 +++++++++++++++++++ 4 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 apps/macos/Tests/ClawdisIPCTests/SessionDataTests.swift create mode 100644 apps/macos/Tests/ClawdisIPCTests/WorkActivityStoreTests.swift diff --git a/apps/macos/Tests/ClawdisIPCTests/CronModelsTests.swift b/apps/macos/Tests/ClawdisIPCTests/CronModelsTests.swift index dd1925545..4db3d3129 100644 --- a/apps/macos/Tests/ClawdisIPCTests/CronModelsTests.swift +++ b/apps/macos/Tests/ClawdisIPCTests/CronModelsTests.swift @@ -39,6 +39,24 @@ struct CronModelsTests { #expect(decoded == payload) } + @Test func scheduleDecodeRejectsUnknownKind() { + let json = """ + {"kind":"wat","atMs":1} + """ + #expect(throws: DecodingError.self) { + _ = try JSONDecoder().decode(CronSchedule.self, from: Data(json.utf8)) + } + } + + @Test func payloadDecodeRejectsUnknownKind() { + let json = """ + {"kind":"wat","text":"hello"} + """ + #expect(throws: DecodingError.self) { + _ = try JSONDecoder().decode(CronPayload.self, from: Data(json.utf8)) + } + } + @Test func displayNameTrimsWhitespaceAndFallsBack() { let base = CronJob( id: "x", @@ -82,4 +100,3 @@ struct CronModelsTests { #expect(job.lastRunDate == Date(timeIntervalSince1970: 1_700_000_050)) } } - diff --git a/apps/macos/Tests/ClawdisIPCTests/SessionDataTests.swift b/apps/macos/Tests/ClawdisIPCTests/SessionDataTests.swift new file mode 100644 index 000000000..8d8e36a54 --- /dev/null +++ b/apps/macos/Tests/ClawdisIPCTests/SessionDataTests.swift @@ -0,0 +1,44 @@ +import Foundation +import Testing +@testable import Clawdis + +@Suite +struct SessionDataTests { + @Test func sessionKindFromKeyDetectsCommonKinds() { + #expect(SessionKind.from(key: "global") == .global) + #expect(SessionKind.from(key: "group:engineering") == .group) + #expect(SessionKind.from(key: "unknown") == .unknown) + #expect(SessionKind.from(key: "user@example.com") == .direct) + } + + @Test func sessionTokenStatsFormatKTokensRoundsAsExpected() { + #expect(SessionTokenStats.formatKTokens(999) == "999") + #expect(SessionTokenStats.formatKTokens(1000) == "1.0k") + #expect(SessionTokenStats.formatKTokens(12_340) == "12k") + } + + @Test func sessionTokenStatsPercentUsedClampsTo100() { + let stats = SessionTokenStats(input: 0, output: 0, total: 250_000, contextTokens: 200_000) + #expect(stats.percentUsed == 100) + } + + @Test func sessionRowFlagLabelsIncludeNonDefaultFlags() { + let row = SessionRow( + id: "x", + key: "user@example.com", + kind: .direct, + updatedAt: Date(), + sessionId: nil, + thinkingLevel: "high", + verboseLevel: "debug", + systemSent: true, + abortedLastRun: true, + tokens: SessionTokenStats(input: 1, output: 2, total: 3, contextTokens: 10), + model: nil) + #expect(row.flagLabels.contains("think high")) + #expect(row.flagLabels.contains("verbose debug")) + #expect(row.flagLabels.contains("system sent")) + #expect(row.flagLabels.contains("aborted")) + } +} + diff --git a/apps/macos/Tests/ClawdisIPCTests/SettingsViewSmokeTests.swift b/apps/macos/Tests/ClawdisIPCTests/SettingsViewSmokeTests.swift index eaf12aa23..bc7bb32d1 100644 --- a/apps/macos/Tests/ClawdisIPCTests/SettingsViewSmokeTests.swift +++ b/apps/macos/Tests/ClawdisIPCTests/SettingsViewSmokeTests.swift @@ -84,6 +84,58 @@ struct SettingsViewSmokeTests { _ = view.body } + @Test func generalSettingsBuildsBody() { + let state = AppState(preview: true) + let view = GeneralSettings(state: state) + _ = view.body + } + + @Test func sessionsSettingsBuildsBody() { + let view = SessionsSettings(rows: SessionRow.previewRows, isPreview: true) + _ = view.body + } + + @Test func instancesSettingsBuildsBody() { + let store = InstancesStore(isPreview: true) + store.instances = [ + InstanceInfo( + id: "local", + host: "this-mac", + ip: "127.0.0.1", + version: "1.0", + platform: "macos 15.0", + lastInputSeconds: 12, + mode: "local", + reason: "test", + text: "test instance", + ts: Date().timeIntervalSince1970 * 1000), + ] + let view = InstancesSettings(store: store) + _ = view.body + } + + @Test func permissionsSettingsBuildsBody() { + let view = PermissionsSettings( + status: [ + .notifications: true, + .screenRecording: false, + ], + refresh: {}, + showOnboarding: {}) + _ = view.body + } + + @Test func settingsRootViewBuildsBody() { + let state = AppState(preview: true) + let view = SettingsRootView(state: state, updater: nil, initialTab: .general) + _ = view.body + } + + @Test func aboutSettingsBuildsBody() { + let view = AboutSettings(updater: nil) + _ = view.body + } + @Test func voiceWakeSettingsBuildsBody() { let state = AppState(preview: true) let view = VoiceWakeSettings(state: state) @@ -95,4 +147,3 @@ struct SettingsViewSmokeTests { _ = view.body } } - diff --git a/apps/macos/Tests/ClawdisIPCTests/WorkActivityStoreTests.swift b/apps/macos/Tests/ClawdisIPCTests/WorkActivityStoreTests.swift new file mode 100644 index 000000000..e899a3c12 --- /dev/null +++ b/apps/macos/Tests/ClawdisIPCTests/WorkActivityStoreTests.swift @@ -0,0 +1,68 @@ +import Foundation +import Testing +@testable import Clawdis + +@Suite +@MainActor +struct WorkActivityStoreTests { + @Test func mainSessionJobPreemptsOther() { + let store = WorkActivityStore() + + store.handleJob(sessionKey: "group:1", state: "started") + #expect(store.iconState == .workingOther(.job)) + #expect(store.current?.sessionKey == "group:1") + + store.handleJob(sessionKey: "main", state: "started") + #expect(store.iconState == .workingMain(.job)) + #expect(store.current?.sessionKey == "main") + + store.handleJob(sessionKey: "main", state: "finished") + #expect(store.iconState == .workingOther(.job)) + #expect(store.current?.sessionKey == "group:1") + + store.handleJob(sessionKey: "group:1", state: "finished") + #expect(store.iconState == .idle) + #expect(store.current == nil) + } + + @Test func toolLabelExtractsFirstLineAndShortensHome() { + let store = WorkActivityStore() + let home = NSHomeDirectory() + + store.handleTool( + sessionKey: "main", + phase: "start", + name: "bash", + meta: nil, + args: [ + "command": AnyCodable("echo hi\necho bye"), + "path": AnyCodable("\(home)/Projects/clawdis"), + ]) + + #expect(store.current?.label == "bash: echo hi") + #expect(store.iconState == .workingMain(.tool(.bash))) + + store.handleTool( + sessionKey: "main", + phase: "start", + name: "read", + meta: nil, + args: ["path": AnyCodable("\(home)/secret.txt")]) + + #expect(store.current?.label == "read: ~/secret.txt") + #expect(store.iconState == .workingMain(.tool(.read))) + } + + @Test func resolveIconStateHonorsOverrideSelection() { + let store = WorkActivityStore() + store.handleJob(sessionKey: "main", state: "started") + #expect(store.iconState == .workingMain(.job)) + + store.resolveIconState(override: .idle) + #expect(store.iconState == .idle) + + store.resolveIconState(override: .otherEdit) + #expect(store.iconState == .overridden(.tool(.edit))) + } +} +