apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README

RadrootsAppleMediaPickerTests.swift (3458B)


      1 import Foundation
      2 import Testing
      3 @testable import RadrootsKit
      4 
      5 @Test func captureAsyncSupportRunsCleanupOnTimeout() async throws {
      6     let probe = RadrootsCaptureCleanupProbe()
      7 
      8     await #expect(throws: RadrootsCaptureIntakeError.transientFailure("timeout")) {
      9         let _: Int = try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback(
     10             timeout: 0.001,
     11             timeoutMessage: "timeout"
     12         ) { _, setCleanup in
     13             setCleanup {
     14                 probe.recordCleanup()
     15             }
     16         }
     17     }
     18 
     19     try await Task.sleep(nanoseconds: 20_000_000)
     20     #expect(await probe.cleanupCount == 1)
     21 }
     22 
     23 @Test func captureAsyncSupportRunsCleanupOnceOnDoubleCompletion() async throws {
     24     let probe = RadrootsCaptureCleanupProbe()
     25 
     26     let value: Int = try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback(
     27         timeout: 10,
     28         timeoutMessage: "timeout"
     29     ) { completion, setCleanup in
     30         setCleanup {
     31             probe.recordCleanup()
     32         }
     33         completion(.success(7))
     34         completion(.success(8))
     35     }
     36 
     37     try await Task.sleep(nanoseconds: 20_000_000)
     38     #expect(value == 7)
     39     #expect(await probe.cleanupCount == 1)
     40 }
     41 
     42 @Test func captureAsyncSupportRunsCleanupOnTaskCancellation() async throws {
     43     let probe = RadrootsCaptureCleanupProbe()
     44     let task = Task<Int, any Error> {
     45         try await RadrootsAppleCaptureAsyncSupport.awaitMainActorCallback(
     46             timeout: 10,
     47             timeoutMessage: "timeout"
     48         ) { _, setCleanup in
     49             setCleanup {
     50                 probe.recordCleanup()
     51             }
     52         }
     53     }
     54 
     55     task.cancel()
     56 
     57     await #expect(throws: RadrootsCaptureIntakeError.userCancelled("capture request was cancelled")) {
     58         _ = try await task.value
     59     }
     60     try await Task.sleep(nanoseconds: 20_000_000)
     61     #expect(await probe.cleanupCount == 1)
     62 }
     63 
     64 #if !canImport(UIKit)
     65 @Test func appleMediaPickerReportsUnavailableWithoutUIKit() async throws {
     66     let picker = try RadrootsAppleMediaPicker(fileAccess: mediaPickerTestFileAccess())
     67     let support = try await picker.currentSupport()
     68 
     69     #expect(!support.importAvailable)
     70     #expect(!support.cameraCaptureAvailable)
     71     #expect(support.supportedImportKinds.isEmpty)
     72     #expect(support.supportedCaptureKinds.isEmpty)
     73 
     74     await #expect(throws: RadrootsCaptureIntakeError.unavailable("media import is unavailable")) {
     75         _ = try await picker.importMedia(try RadrootsMediaImportRequest())
     76     }
     77     await #expect(throws: RadrootsCaptureIntakeError.unavailable("camera photo capture is unavailable")) {
     78         _ = try await picker.captureMedia(try RadrootsMediaCaptureRequest())
     79     }
     80 }
     81 #endif
     82 
     83 private func mediaPickerTestFileAccess() throws -> RadrootsAppleFileAccess {
     84     let root = FileManager.default.temporaryDirectory
     85         .appendingPathComponent("radroots-media-picker-\(UUID().uuidString)", isDirectory: true)
     86     let roots = try RadrootsAppleFileRoots(
     87         appIdentifier: "org.radroots.media-picker-test",
     88         dataRoot: root.appendingPathComponent("data", isDirectory: true),
     89         cacheRoot: root.appendingPathComponent("cache", isDirectory: true),
     90         temporaryRoot: root.appendingPathComponent("temporary", isDirectory: true)
     91     )
     92     return RadrootsAppleFileAccess(roots: roots)
     93 }
     94 
     95 @MainActor
     96 private final class RadrootsCaptureCleanupProbe {
     97     private(set) var cleanupCount = 0
     98 
     99     func recordCleanup() {
    100         cleanupCount += 1
    101     }
    102 }