From 64b5eb8279baa4283153a54caa36bdede73d7075 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 14 Dec 2025 02:05:50 +0000 Subject: [PATCH] test(ios): add unit test target --- apps/ios/Tests/BridgeEndpointIDTests.swift | 33 +++++++++++++++++++ apps/ios/Tests/Info.plist | 24 ++++++++++++++ .../ios/Tests/VoiceWakePreferencesTests.swift | 26 +++++++++++++++ apps/ios/project.yml | 18 ++++++++++ 4 files changed, 101 insertions(+) create mode 100644 apps/ios/Tests/BridgeEndpointIDTests.swift create mode 100644 apps/ios/Tests/Info.plist create mode 100644 apps/ios/Tests/VoiceWakePreferencesTests.swift diff --git a/apps/ios/Tests/BridgeEndpointIDTests.swift b/apps/ios/Tests/BridgeEndpointIDTests.swift new file mode 100644 index 000000000..e518f30a1 --- /dev/null +++ b/apps/ios/Tests/BridgeEndpointIDTests.swift @@ -0,0 +1,33 @@ +import ClawdisKit +import Network +import Testing +@testable import Clawdis + +@Suite struct BridgeEndpointIDTests { + @Test func stableIDForServiceDecodesAndNormalizesName() { + let endpoint = NWEndpoint.service( + name: "Clawdis\\032Bridge \\032 Iris\n", + type: "_clawdis-bridge._tcp", + domain: "local.", + interface: nil) + + #expect(BridgeEndpointID.stableID(endpoint) == "_clawdis-bridge._tcp|local.|Clawdis Bridge Iris") + } + + @Test func stableIDForNonServiceUsesEndpointDescription() { + let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host("127.0.0.1"), port: 4242) + #expect(BridgeEndpointID.stableID(endpoint) == String(describing: endpoint)) + } + + @Test func prettyDescriptionDecodesBonjourEscapes() { + let endpoint = NWEndpoint.service( + name: "Clawdis\\032Bridge", + type: "_clawdis-bridge._tcp", + domain: "local.", + interface: nil) + + let pretty = BridgeEndpointID.prettyDescription(endpoint) + #expect(pretty == BonjourEscapes.decode(String(describing: endpoint))) + #expect(!pretty.localizedCaseInsensitiveContains("\\032")) + } +} diff --git a/apps/ios/Tests/Info.plist b/apps/ios/Tests/Info.plist new file mode 100644 index 000000000..f0ed04055 --- /dev/null +++ b/apps/ios/Tests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + ClawdisTests + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/apps/ios/Tests/VoiceWakePreferencesTests.swift b/apps/ios/Tests/VoiceWakePreferencesTests.swift new file mode 100644 index 000000000..82976b1be --- /dev/null +++ b/apps/ios/Tests/VoiceWakePreferencesTests.swift @@ -0,0 +1,26 @@ +import Foundation +import Testing +@testable import Clawdis + +@Suite struct VoiceWakePreferencesTests { + @Test func sanitizeTriggerWordsTrimsAndDropsEmpty() { + #expect(VoiceWakePreferences.sanitizeTriggerWords([" clawd ", "", " \nclaude\t"]) == ["clawd", "claude"]) + } + + @Test func sanitizeTriggerWordsFallsBackToDefaultsWhenEmpty() { + #expect(VoiceWakePreferences.sanitizeTriggerWords(["", " "]) == VoiceWakePreferences.defaultTriggerWords) + } + + @Test func displayStringUsesSanitizedWords() { + #expect(VoiceWakePreferences.displayString(for: ["", " "]) == "clawd, claude") + } + + @Test func loadAndSaveTriggerWordsRoundTrip() { + let suiteName = "VoiceWakePreferencesTests.\(UUID().uuidString)" + let defaults = UserDefaults(suiteName: suiteName)! + + #expect(VoiceWakePreferences.loadTriggerWords(defaults: defaults) == VoiceWakePreferences.defaultTriggerWords) + VoiceWakePreferences.saveTriggerWords(["computer"], defaults: defaults) + #expect(VoiceWakePreferences.loadTriggerWords(defaults: defaults) == ["computer"]) + } +} diff --git a/apps/ios/project.yml b/apps/ios/project.yml index b51e1093b..2da19ab13 100644 --- a/apps/ios/project.yml +++ b/apps/ios/project.yml @@ -58,3 +58,21 @@ targets: NSCameraUsageDescription: Clawdis can capture photos or short video clips when requested via the bridge. NSMicrophoneUsageDescription: Clawdis needs microphone access for voice wake. NSSpeechRecognitionUsageDescription: Clawdis uses on-device speech recognition for voice wake. + + ClawdisTests: + type: bundle.unit-test + platform: iOS + sources: + - path: Tests + dependencies: + - target: Clawdis + settings: + base: + PRODUCT_BUNDLE_IDENTIFIER: com.steipete.clawdis.ios.tests + SWIFT_VERSION: "6.0" + TEST_HOST: "$(BUILT_PRODUCTS_DIR)/Clawdis.app/Clawdis" + BUNDLE_LOADER: "$(TEST_HOST)" + info: + path: Tests/Info.plist + properties: + CFBundleDisplayName: ClawdisTests