-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: New ItemProviderPropertyValueRepresentation to Use an ItemProvi…
…der wrapping a property list test: Testing ItemProviderPropertyValueRepresentation
- Loading branch information
1 parent
254b414
commit c94da92
Showing
2 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
...s/InfomaniakCore/ItemProviderRepresentation/ItemProviderPropertyValueRepresentation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
Infomaniak Mail - iOS App | ||
Copyright (C) 2024 Infomaniak Network SA | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
import Foundation | ||
|
||
/// Something that can provide a `Progress` and an async `Result` | ||
/// from a `NSItemProvider` that is conforming to propertyList UTI | ||
/// | ||
/// Returns arbitrary Dictionary | ||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) | ||
public final class ItemProviderPropertyValueRepresentation: NSObject, ProgressResultable { | ||
/// Progress increment size | ||
private static let progressStep: Int64 = 1 | ||
|
||
/// Number of steps to complete the task | ||
private static let totalSteps: Int64 = 1 | ||
|
||
/// Something to transform events to a nice `async Result` | ||
private let flowToAsync = FlowToAsyncResult<Success>() | ||
|
||
private let itemProvider: NSItemProvider | ||
|
||
/// Domain specific errors | ||
public enum ErrorDomain: Error, Equatable { | ||
/// loadItem cast failed | ||
case unableToReadDictionary | ||
} | ||
|
||
public typealias Success = NSDictionary | ||
public typealias Failure = Error | ||
|
||
public init(from itemProvider: NSItemProvider) { | ||
progress = Progress(totalUnitCount: Self.totalSteps) | ||
|
||
self.itemProvider = itemProvider | ||
super.init() | ||
|
||
Task { | ||
let completionProgress = Progress(totalUnitCount: Self.totalSteps) | ||
progress.addChild(completionProgress, withPendingUnitCount: Self.progressStep) | ||
|
||
defer { | ||
completionProgress.completedUnitCount += Self.progressStep | ||
} | ||
|
||
let propertyListIdentifier = UTI.propertyList.identifier | ||
if self.itemProvider.hasItemConformingToTypeIdentifier(propertyListIdentifier) { | ||
guard let resultDictionary = try await self.itemProvider | ||
.loadItem(forTypeIdentifier: propertyListIdentifier) as? NSDictionary else { | ||
flowToAsync.sendFailure(ErrorDomain.unableToReadDictionary) | ||
return | ||
} | ||
|
||
flowToAsync.sendSuccess(resultDictionary) | ||
|
||
} else { | ||
flowToAsync.sendFailure(ErrorDomain.unableToReadDictionary) | ||
} | ||
} | ||
} | ||
|
||
// MARK: ProgressResultable | ||
|
||
public var progress: Progress | ||
|
||
public var result: Result<Success, Failure> { | ||
get async { | ||
return await flowToAsync.result | ||
} | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
...iakCoreTests/UTItemProviderRepresentation/UTItemProviderPropertyValueRepresentation.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
Infomaniak Core - iOS | ||
Copyright (C) 2024 Infomaniak Network SA | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
import Foundation | ||
import InfomaniakCore | ||
@testable import InfomaniakDI | ||
import XCTest | ||
|
||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) | ||
final class UTItemProviderPropertyValueRepresentation: XCTestCase { | ||
private let fileManager = FileManager.default | ||
|
||
override func setUp() { | ||
let factory = Factory( | ||
type: AppGroupPathProvidable.self | ||
) { _, _ in | ||
return AppGroupPathProvider(realmRootPath: "realm", appGroupIdentifier: "com.ik.test")! | ||
} | ||
SimpleResolver.sharedResolver.store(factory: factory) | ||
} | ||
|
||
override func tearDown() { | ||
SimpleResolver.sharedResolver.removeAll() | ||
} | ||
|
||
// MARK: - | ||
|
||
func testProvideDictionary() async { | ||
// GIVEN | ||
let someDictionary: NSDictionary = ["key": "value"] | ||
let item = NSItemProvider(item: someDictionary, typeIdentifier: UTI.propertyList.identifier) | ||
|
||
let provider = ItemProviderPropertyValueRepresentation(from: item) | ||
XCTAssertFalse(provider.progress.isFinished) | ||
|
||
do { | ||
// WHEN | ||
let result = try await provider.result.get() | ||
|
||
// THEN | ||
XCTAssertEqual(result, someDictionary) | ||
XCTAssertTrue(provider.progress.isFinished) | ||
} catch { | ||
XCTFail("Unexpected error:\(error)") | ||
} | ||
} | ||
|
||
func testUnableToProvideDictionary() async { | ||
// GIVEN | ||
let garbageInput = "la li lu le lo" as NSSecureCoding | ||
let item = NSItemProvider(item: garbageInput, typeIdentifier: UTI.propertyList.identifier) | ||
|
||
let provider = ItemProviderPropertyValueRepresentation(from: item) | ||
XCTAssertFalse(provider.progress.isFinished) | ||
|
||
do { | ||
// WHEN | ||
let result = try await provider.result.get() | ||
|
||
// THEN | ||
XCTFail("Should throw. got \(result)") | ||
} catch { | ||
guard let error = error as? ItemProviderPropertyValueRepresentation.ErrorDomain else { | ||
XCTFail("Unexpected error :\(error)") | ||
return | ||
} | ||
|
||
guard error == .unableToReadDictionary else { | ||
XCTFail("Unexpected domain error :\(error)") | ||
return | ||
} | ||
|
||
XCTAssertTrue(provider.progress.isFinished) | ||
} | ||
} | ||
} |