apple_kit

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

RadrootsAppleMediaPickerTests.swift (3393B)


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