Fixed the build errors and unit tests

pull/894/head
Morgan Pretty 12 months ago
parent 72525ae37b
commit 7f2508d2d0

@ -11,7 +11,9 @@ abstract_target 'GlobalDependencies' do
# FIXME: Would be nice to migrate from CocoaPods to SwiftPackageManager (should allow us to speed up build time), haven't gone through all of the dependencies but currently unfortunately SQLCipher doesn't support SPM (for more info see: https://github.com/sqlcipher/sqlcipher/issues/371)
pod 'SQLCipher', '~> 4.5.3'
pod 'WebRTC-lib'
# FIXME: We are currently stuck at version '116.0.0' due to a linker issue described here: https://github.com/stasel/WebRTC/issues/83
pod 'WebRTC-lib', '116.0.0'
target 'Session' do
pod 'Reachability'

@ -2,13 +2,22 @@ PODS:
- CocoaLumberjack (3.8.5):
- CocoaLumberjack/Core (= 3.8.5)
- CocoaLumberjack/Core (3.8.5)
- CwlCatchException (2.2.0):
- CwlCatchExceptionSupport (~> 2.2.0)
- CwlCatchExceptionSupport (2.2.0)
- CwlMachBadInstructionHandler (2.2.0)
- CwlPosixPreconditionTesting (2.2.0)
- CwlPreconditionTesting (2.2.1):
- CwlCatchException (~> 2.2.0)
- CwlMachBadInstructionHandler (~> 2.2.0)
- CwlPosixPreconditionTesting (~> 2.2.0)
- DifferenceKit (1.3.0):
- DifferenceKit/Core (= 1.3.0)
- DifferenceKit/UIKitExtension (= 1.3.0)
- DifferenceKit/Core (1.3.0)
- DifferenceKit/UIKitExtension (1.3.0):
- DifferenceKit/Core
- GRDB.swift/SQLCipher (6.13.0):
- GRDB.swift/SQLCipher (6.24.1):
- SQLCipher (>= 3.4.2)
- libwebp (1.3.2):
- libwebp/demux (= 1.3.2)
@ -22,24 +31,25 @@ PODS:
- libwebp/sharpyuv (1.3.2)
- libwebp/webp (1.3.2):
- libwebp/sharpyuv
- Nimble (12.3.0)
- NVActivityIndicatorView (5.1.1):
- NVActivityIndicatorView/Base (= 5.1.1)
- NVActivityIndicatorView/Base (5.1.1)
- OpenSSL-Universal (1.1.2200)
- Quick (7.3.0)
- Reachability (3.2)
- Nimble (13.3.0):
- CwlPreconditionTesting (~> 2.2.0)
- NVActivityIndicatorView (5.2.0):
- NVActivityIndicatorView/Base (= 5.2.0)
- NVActivityIndicatorView/Base (5.2.0)
- OpenSSL-Universal (3.1.5004)
- Quick (7.5.0)
- Reachability (3.7.6)
- SAMKeychain (1.5.3)
- SignalCoreKit (1.0.0):
- CocoaLumberjack
- OpenSSL-Universal
- SQLCipher (4.5.3):
- SQLCipher/standard (= 4.5.3)
- SQLCipher/common (4.5.3)
- SQLCipher/standard (4.5.3):
- SQLCipher (4.5.7):
- SQLCipher/standard (= 4.5.7)
- SQLCipher/common (4.5.7)
- SQLCipher/standard (4.5.7):
- SQLCipher/common
- SwiftProtobuf (1.5.0)
- WebRTC-lib (114.0.0)
- WebRTC-lib (116.0.0)
- YYImage/Core (1.0.4)
- YYImage/libwebp (1.0.4):
- libwebp
@ -56,12 +66,17 @@ DEPENDENCIES:
- SignalCoreKit (from `https://github.com/oxen-io/session-ios-core-kit`, commit `3acbfe5`)
- SQLCipher (~> 4.5.3)
- SwiftProtobuf (~> 1.5.0)
- WebRTC-lib
- WebRTC-lib (= 116.0.0)
- YYImage/libwebp (from `https://github.com/signalapp/YYImage`)
SPEC REPOS:
trunk:
- CocoaLumberjack
- CwlCatchException
- CwlCatchExceptionSupport
- CwlMachBadInstructionHandler
- CwlPosixPreconditionTesting
- CwlPreconditionTesting
- DifferenceKit
- GRDB.swift
- libwebp
@ -92,21 +107,26 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
CocoaLumberjack: 6a459bc897d6d80bd1b8c78482ec7ad05dffc3f0
CwlCatchException: 51bf8319009a31104ea6f0568730d1ecc25b6454
CwlCatchExceptionSupport: 1345d6adb01a505933f2bc972dab60dcb9ce3e50
CwlMachBadInstructionHandler: ea1030428925d9bf340882522af30712fb4bf356
CwlPosixPreconditionTesting: a125dee731883f2582715f548c6b6c92c7fde145
CwlPreconditionTesting: ccfd08aca58d14e04062b2a3dd2fd52e09857453
DifferenceKit: ab185c4d7f9cef8af3fcf593e5b387fb81e999ca
GRDB.swift: fe420b1af49ec519c7e96e07887ee44f5dfa2b78
GRDB.swift: 136dcb5d8dddca50aae3ba7d77475f79e7232cd8
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
Nimble: f8a8219d16f176429b951e8f7e72df5c23ceddc0
NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667
OpenSSL-Universal: 6e1ae0555546e604dbc632a2b9a24a9c46c41ef6
Quick: d32871931c05547cb4e0bc9009d66a18b50d8558
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
Nimble: 3ac6c6b0b7e9835d1540b6507d8054b12a415536
NVActivityIndicatorView: fe52a6a68664c2df8991d7d9e3d86d8d19453c53
OpenSSL-Universal: 0db2e81615ad95efc90ce13a638986858da38c0d
Quick: 2b651168441479b949ba987f3cee41a9cc53aa32
Reachability: fd0ecd23705e2599e4cceeb943222ae02296cbc6
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
SignalCoreKit: 1fbd8732163ef76de16cd1107d1fa3684b607e5d
SQLCipher: 57fa9f863fa4a3ed9dd3c90ace52315db8c0fdca
SQLCipher: 5e6bfb47323635c8b657b1b27d25c5f1baf63bf5
SwiftProtobuf: 241400280f912735c1e1b9fe675fdd2c6c4d42e2
WebRTC-lib: d83df8976fa608b980f1d85796b3de66d60a1953
WebRTC-lib: a7f14febc57a4bb334505ea33eb4f797ef9e3ac9
YYImage: f1ddd15ac032a58b78bbed1e012b50302d318331
PODFILE CHECKSUM: 2c877a533db6e82eaa94407c95be114d80c2f893
PODFILE CHECKSUM: 05cf9cc64f43765bbe411901b641f1c66304993d
COCOAPODS: 1.15.2

@ -239,7 +239,7 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
let conversationVC: ConversationVC = (presentingVC as? TopBannerController)?.wrappedViewController() as? ConversationVC,
conversationVC.viewModel.threadData.threadId == call.sessionId
{
let callVC = CallVC(for: call)
let callVC = CallVC(for: call, using: dependencies)
callVC.conversationVC = conversationVC
conversationVC.inputAccessoryView?.isHidden = true
conversationVC.inputAccessoryView?.alpha = 0

@ -170,8 +170,7 @@ extension ContextMenuVC {
currentUserIsOpenGroupModerator: Bool,
currentThreadIsMessageRequest: Bool,
forMessageInfoScreen: Bool,
delegate: ContextMenuActionDelegate?,
using dependencies: Dependencies
delegate: ContextMenuActionDelegate?
) -> [Action]? {
switch cellViewModel.variant {
case .standardIncomingDeleted, .infoCall, .infoScreenshotNotification, .infoMediaSavedNotification,
@ -251,16 +250,16 @@ extension ContextMenuVC {
(canCopy ? Action.copy(cellViewModel, delegate) : nil),
(canSave ? Action.save(cellViewModel, delegate) : nil),
(canCopySessionId ? Action.copySessionID(cellViewModel, delegate) : nil),
(canDelete ? Action.delete(cellViewModel, delegate, using: dependencies) : nil),
(canBan ? Action.ban(cellViewModel, delegate, using: dependencies) : nil),
(canBan ? Action.banAndDeleteAllMessages(cellViewModel, delegate, using: dependencies) : nil),
(forMessageInfoScreen ? nil : Action.info(cellViewModel, delegate, using: dependencies)),
(canDelete ? Action.delete(cellViewModel, delegate) : nil),
(canBan ? Action.ban(cellViewModel, delegate) : nil),
(canBan ? Action.banAndDeleteAllMessages(cellViewModel, delegate) : nil),
(forMessageInfoScreen ? nil : Action.info(cellViewModel, delegate)),
]
.appending(
contentsOf: (shouldShowEmojiActions ? recentEmojis : [])
.map { Action.react(cellViewModel, $0, delegate) }
)
.appending(forMessageInfoScreen ? nil : Action.emojiPlusButton(cellViewModel, delegate, using: dependencies))
.appending(forMessageInfoScreen ? nil : Action.emojiPlusButton(cellViewModel, delegate))
.compactMap { $0 }
guard !generatedActions.isEmpty else { return [] }

@ -1883,27 +1883,28 @@ extension ConversationVC:
// MARK: - ContextMenuActionDelegate
func info(_ cellViewModel: MessageViewModel, using dependencies: Dependencies) {
func info(_ cellViewModel: MessageViewModel) {
let actions: [ContextMenuVC.Action] = ContextMenuVC.actions(
for: cellViewModel,
recentEmojis: [],
currentUserPublicKey: self.viewModel.threadData.currentUserPublicKey,
currentUserBlinded15PublicKey: self.viewModel.threadData.currentUserBlinded15PublicKey,
currentUserBlinded25PublicKey: self.viewModel.threadData.currentUserBlinded25PublicKey,
currentUserSessionId: self.viewModel.threadData.currentUserSessionId,
currentUserBlinded15SessionId: self.viewModel.threadData.currentUserBlinded15SessionId,
currentUserBlinded25SessionId: self.viewModel.threadData.currentUserBlinded25SessionId,
currentUserIsOpenGroupModerator: OpenGroupManager.isUserModeratorOrAdmin(
self.viewModel.threadData.currentUserPublicKey,
publicKey: self.viewModel.threadData.currentUserSessionId,
for: self.viewModel.threadData.openGroupRoomToken,
on: self.viewModel.threadData.openGroupServer
on: self.viewModel.threadData.openGroupServer,
using: viewModel.dependencies
),
currentThreadIsMessageRequest: (self.viewModel.threadData.threadIsMessageRequest == true),
forMessageInfoScreen: true,
delegate: self,
using: viewModel.dependencies
delegate: self
) ?? []
let messageInfoViewController = MessageInfoViewController(
actions: actions,
messageViewModel: cellViewModel
messageViewModel: cellViewModel,
using: viewModel.dependencies
)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
self?.navigationController?.pushViewController(messageInfoViewController, animated: true)

@ -1001,7 +1001,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
to: .contact(publicKey: cellViewModel.threadId),
namespace: .default,
interactionId: nil,
fileIds: []
fileIds: [],
using: dependencies
)),
.preparedRequest(try SnodeAPI
.preparedDeleteMessages(
@ -1046,7 +1047,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
to: .contact(publicKey: cellViewModel.threadId),
namespace: .default,
interactionId: nil,
fileIds: []
fileIds: [],
using: dependencies
)),
.preparedRequest(try SnodeAPI
.preparedDeleteMessages(
@ -1096,7 +1098,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
to: .closedGroup(groupPublicKey: cellViewModel.threadId),
namespace: .legacyClosedGroup,
interactionId: nil,
fileIds: []
fileIds: [],
using: dependencies
)),
.deleteFromDatabase(cellViewModel.id)
]
@ -1136,7 +1139,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
to: .closedGroup(groupPublicKey: cellViewModel.threadId),
namespace: .groupMessages,
interactionId: nil,
fileIds: []
fileIds: [],
using: dependencies
)),
.deleteFromDatabase(cellViewModel.id)
]
@ -1179,7 +1183,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
to: .closedGroup(groupPublicKey: cellViewModel.threadId),
namespace: .groupMessages,
interactionId: nil,
fileIds: []
fileIds: [],
using: dependencies
)),
.preparedRequest(try SnodeAPI
.preparedDeleteMessages(

@ -39,7 +39,7 @@ struct OpenGroupInvitationView_SwiftUI: View {
// Icon
let iconName = (isOutgoing ? "Globe" : "Plus")
if let iconImage = UIImage(named: iconName)?
.resizedImage(to: CGSize(width: Self.iconSize, height: Self.iconSize))?
.resized(to: CGSize(width: Self.iconSize, height: Self.iconSize))?
.withRenderingMode(.alwaysTemplate)
{
Image(uiImage: iconImage)

@ -13,9 +13,9 @@ struct QuoteView_SwiftUI: View {
var authorId: String
var quotedText: String?
var threadVariant: SessionThread.Variant
var currentUserPublicKey: String?
var currentUserBlinded15PublicKey: String?
var currentUserBlinded25PublicKey: String?
var currentUserSessionId: String?
var currentUserBlinded15SessionId: String?
var currentUserBlinded25SessionId: String?
var direction: Direction
var attachment: Attachment?
}
@ -34,9 +34,9 @@ struct QuoteView_SwiftUI: View {
private var isCurrentUser: Bool {
return [
info.currentUserPublicKey,
info.currentUserBlinded15PublicKey,
info.currentUserBlinded25PublicKey
info.currentUserSessionId,
info.currentUserBlinded15SessionId,
info.currentUserBlinded25SessionId
]
.compactMap { $0 }
.asSet()
@ -95,9 +95,9 @@ struct QuoteView_SwiftUI: View {
return thumbnail
}
let fallbackImageName: String = (MIMETypeUtil.isAudio(attachment.contentType) ? "attachment_audio" : "actionsheet_document_black")
let fallbackImageName: String = (MimeTypeUtil.isAudio(attachment.contentType) ? "attachment_audio" : "actionsheet_document_black")
return UIImage(named: fallbackImageName)?
.resizedImage(to: CGSize(width: Self.iconSize, height: Self.iconSize))?
.resized(to: CGSize(width: Self.iconSize, height: Self.iconSize))?
.withRenderingMode(.alwaysTemplate)
}() {
Image(uiImage: image)
@ -159,9 +159,9 @@ struct QuoteView_SwiftUI: View {
MentionUtilities.highlightMentions(
in: quotedText,
threadVariant: info.threadVariant,
currentUserPublicKey: info.currentUserPublicKey,
currentUserBlinded15PublicKey: info.currentUserBlinded15PublicKey,
currentUserBlinded25PublicKey: info.currentUserBlinded25PublicKey,
currentUserSessionId: info.currentUserSessionId,
currentUserBlinded15SessionId: info.currentUserBlinded15SessionId,
currentUserBlinded25SessionId: info.currentUserBlinded25SessionId,
isOutgoingMessage: (info.direction == .outgoing),
textColor: textColor,
theme: ThemeManager.currentTheme,

@ -15,6 +15,7 @@ struct MessageInfoScreen: View {
var actions: [ContextMenuVC.Action]
var messageViewModel: MessageViewModel
let dependencies: Dependencies
var isMessageFailed: Bool {
return [.failed, .failedToSync].contains(messageViewModel.state)
}
@ -237,7 +238,7 @@ struct MessageInfoScreen: View {
size: .message,
publicKey: messageViewModel.authorId,
threadVariant: .contact, // Always show the display picture in 'contact' mode
customImageData: nil,
displayPictureFilename: nil,
profile: messageViewModel.profile,
profileIcon: (messageViewModel.isSenderOpenGroupModerator ? .crown : .none)
)
@ -355,7 +356,8 @@ struct MessageInfoScreen: View {
interactionId: messageViewModel.id,
selectedAttachmentId: attachment.id,
options: [ .sliderEnabled ],
useTransitioningDelegate: false
useTransitioningDelegate: false,
using: dependencies
) {
self.host.controller?.present(mediaGalleryView, animated: true)
}
@ -421,9 +423,9 @@ struct MessageBubble: View {
authorId: quote.authorId,
quotedText: quote.body,
threadVariant: messageViewModel.threadVariant,
currentUserPublicKey: messageViewModel.currentUserPublicKey,
currentUserBlinded15PublicKey: messageViewModel.currentUserBlinded15PublicKey,
currentUserBlinded25PublicKey: messageViewModel.currentUserBlinded25PublicKey,
currentUserSessionId: messageViewModel.currentUserSessionId,
currentUserBlinded15SessionId: messageViewModel.currentUserBlinded15SessionId,
currentUserBlinded25SessionId: messageViewModel.currentUserBlinded25SessionId,
direction: (messageViewModel.variant == .standardOutgoing ? .outgoing : .incoming),
attachment: messageViewModel.quoteAttachment
)
@ -531,10 +533,15 @@ struct InfoBlock<Content>: View where Content: View {
}
final class MessageInfoViewController: SessionHostingViewController<MessageInfoScreen> {
init(actions: [ContextMenuVC.Action], messageViewModel: MessageViewModel) {
init(
actions: [ContextMenuVC.Action],
messageViewModel: MessageViewModel,
using dependencies: Dependencies
) {
let messageInfoView = MessageInfoScreen(
actions: actions,
messageViewModel: messageViewModel
messageViewModel: messageViewModel,
dependencies: dependencies
)
super.init(rootView: messageInfoView)
@ -585,16 +592,17 @@ struct MessageInfoView_Previews: PreviewProvider {
static var actions: [ContextMenuVC.Action] {
return [
.reply(messageViewModel, nil, using: Dependencies()),
.retry(messageViewModel, nil, using: Dependencies()),
.delete(messageViewModel, nil, using: Dependencies())
.reply(messageViewModel, nil),
.retry(messageViewModel, nil),
.delete(messageViewModel, nil)
]
}
static var previews: some View {
MessageInfoScreen(
actions: actions,
messageViewModel: messageViewModel
messageViewModel: messageViewModel,
dependencies: Dependencies()
)
}
}

@ -33,10 +33,6 @@ public class AppEnvironment {
}
public func setup() {
// Hang certain singletons on Environment too.
SessionEnvironment.shared?.notificationsManager.mutate {
$0 = notificationPresenter
}
setupLogFiles()
}

@ -2,6 +2,7 @@
import UIKit
import SignalCoreKit
import SessionUIKit
import SessionUtilitiesKit
final class MainAppContext: AppContext {
@ -143,6 +144,9 @@ final class MainAppContext: AppContext {
func setMainWindow(_ mainWindow: UIWindow) {
self.mainWindow = mainWindow
// Store in SessionUIKit to avoid needing the SessionUtilitiesKit dependency
SNUIKit.setMainWindow(mainWindow)
}
func beginBackgroundTask(expirationHandler: @escaping () -> ()) -> UIBackgroundTaskIdentifier {

@ -1,6 +1,7 @@
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import SwiftUI
import SessionMessagingKit
public struct SessionCarouselView_SwiftUI: View {
@Binding var index: Int

@ -450,8 +450,8 @@ extension WebRTCSession {
let audioSession = RTCAudioSession.sharedInstance()
audioSession.lockForConfiguration()
do {
try audioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue)
try audioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
try audioSession.setMode(AVAudioSession.Mode.voiceChat)
try audioSession.overrideOutputAudioPort(outputAudioPort)
try audioSession.setActive(true)
} catch let error {

@ -132,8 +132,8 @@ public extension Profile {
// If we have both a `profileKey` and a `profilePicture` then the key MUST be valid
if
let profileKeyData: Data = try? container.decode(Data.self, forKey: .profileEncryptionKey),
let profilePictureUrlValue: String = try? container.decode(String.self, forKey: .profilePictureUrl)
let profileKeyData: Data = try? container.decode(Data?.self, forKey: .profileEncryptionKey),
let profilePictureUrlValue: String = try? container.decode(String?.self, forKey: .profilePictureUrl)
{
profileKey = profileKeyData
profilePictureUrl = profilePictureUrlValue

@ -94,7 +94,7 @@ public enum AttachmentUploadJob: JobExecutor {
db,
message: details.message,
destination: nil,
with: .other("[AttachmentUploadJob] Failed", error),
error: .other("[AttachmentUploadJob] Failed", error),
interactionId: interactionId,
using: dependencies
)

@ -73,7 +73,6 @@ public enum GroupInviteMemberJob: JobExecutor {
namespace: .default,
interactionId: nil,
fileIds: [],
isSyncMessage: false,
using: dependencies
)
}

@ -73,7 +73,6 @@ public enum GroupLeavingJob: JobExecutor {
namespace: destination.defaultNamespace,
interactionId: job.interactionId,
fileIds: [],
isSyncMessage: false,
using: dependencies
)
)
@ -87,7 +86,6 @@ public enum GroupLeavingJob: JobExecutor {
namespace: destination.defaultNamespace,
interactionId: job.interactionId,
fileIds: [],
isSyncMessage: false,
using: dependencies
)
)

@ -59,7 +59,6 @@ public enum GroupPromoteMemberJob: JobExecutor {
namespace: .default,
interactionId: nil,
fileIds: [],
isSyncMessage: false,
using: dependencies
)
}

@ -198,12 +198,12 @@ public enum MessageSendJob: JobExecutor {
// In this case the `MessageSender` process gets cancelled so we need to
// call `handleFailedMessageSend` to update the statuses correctly
dependencies.storage.read(using: dependencies) { db in
dependencies[singleton: .storage].read(using: dependencies) { db in
MessageSender.handleFailedMessageSend(
db,
message: details.message,
destination: details.destination,
with: .sendJobTimeout,
error: .sendJobTimeout,
interactionId: job.interactionId,
using: dependencies
)

@ -43,7 +43,9 @@ public enum SendReadReceiptsJob: JobExecutor {
),
to: details.destination,
namespace: details.destination.defaultNamespace,
interactionId: nil
interactionId: nil,
fileIds: [],
using: dependencies
)
}
.flatMap { $0.send(using: dependencies) }

@ -52,11 +52,7 @@ public enum MessageSenderError: Error, CustomStringConvertible, Equatable {
case .noKeyPair: return "Couldn't find a private key associated with the given group public key (MessageSenderError.noKeyPair)."
case .invalidClosedGroupUpdate: return "Invalid group update (MessageSenderError.invalidClosedGroupUpdate)."
case .invalidConfigMessageHandling: return "Invalid handling of a config message (MessageSenderError.invalidConfigMessageHandling)."
case .other(let error):
switch error {
case is CustomStringConvertible: return "\(error)"
default: return error.localizedDescription
}
case .other(_, let error): return "\(error)"
}
}

@ -1924,8 +1924,7 @@ class MessageReceiverGroupsSpec: QuickSpec {
ed25519SecretKey: Array(groupSecretKey)
),
using: dependencies
),
isSyncMessage: false
)
)
),
canStartJob: true,

@ -1162,8 +1162,7 @@ class MessageSenderGroupsSpec: QuickSpec {
ed25519SecretKey: Array(groupSecretKey)
),
using: dependencies
),
isSyncMessage: false
)
)
),
dependantJob: nil,

@ -64,7 +64,6 @@ class MessageSenderSpec: QuickSpec {
namespace: .default,
interactionId: nil,
fileIds: [],
isSyncMessage: false,
using: dependencies
)
}

@ -1248,15 +1248,6 @@ public extension Publisher where Output == Set<Snode> {
return try transform(snode)
.eraseToAnyPublisher()
}
.mapError { error in
// Prevent nesting the 'ranOutOfRandomSnodes' errors
switch error {
case SnodeAPIError.ranOutOfRandomSnodes: break
default: lastError = error
}
return error
}
.retry(retries)
.eraseToAnyPublisher()
}

@ -5,6 +5,8 @@ import GRDB
import SessionUtilitiesKit
public enum SNUIKit: MigratableTarget {
internal static let mainWindow: Atomic<UIWindow?> = Atomic(nil)
public static func migrations() -> TargetMigrations {
return TargetMigrations(
identifier: .uiKit,
@ -25,4 +27,8 @@ public enum SNUIKit: MigratableTarget {
public static func configure() {
}
public static func setMainWindow(_ mainWindow: UIWindow) {
SNUIKit.mainWindow.mutate { $0 = mainWindow }
}
}

@ -10,7 +10,7 @@ struct ViewControllerHolder {
struct ViewControllerKey: EnvironmentKey {
static var defaultValue: ViewControllerHolder {
return ViewControllerHolder(value: Singleton.appContext.mainWindow?.rootViewController)
return ViewControllerHolder(value: SNUIKit.mainWindow.wrappedValue?.rootViewController)
}
}

@ -2,6 +2,7 @@
import Foundation
import Nimble
import CwlPreconditionTesting
import SessionUtilitiesKit
public enum CallAmount {
@ -41,8 +42,8 @@ public func call<M, T, R>(
matchingParameters: ParameterMatchType = .none,
exclusive: Bool = false,
functionBlock: @escaping (inout T) throws -> R
) -> Nimble.Predicate<M> where M: Mock<T> {
return Predicate.define { actualExpression in
) -> Matcher<M> where M: Mock<T> {
return Matcher.define { actualExpression in
/// First generate the call info
let callInfo: CallInfo = generateCallInfo(actualExpression, functionBlock)
let expectedDescription: String = {
@ -74,7 +75,7 @@ public func call<M, T, R>(
/// If an exception was thrown when generating call info then fail (mock value likely invalid)
guard callInfo.caughtException == nil else {
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -85,7 +86,7 @@ public func call<M, T, R>(
/// If there is no function within the 'callInfo' then we can't provide more useful info
guard let targetFunction: MockFunction = callInfo.targetFunction else {
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -96,7 +97,7 @@ public func call<M, T, R>(
/// If the mock wasn't called at all then no other data will be useful
guard !callInfo.allFunctionsCalled.isEmpty else {
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -118,7 +119,7 @@ public func call<M, T, R>(
.map { "\($0.name) (params: \($0.paramCount))" }
.filter { $0 != "\(callInfo.functionName) (params: \(callInfo.parameterCount))" }
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -181,7 +182,7 @@ public func call<M, T, R>(
switch (exclusive, metCallCountRequirement, allCallsMetParamRequirements, totalUniqueParamCount) {
/// No calls with the matching parameter requirements but only one parameter combination so include the param info
case (_, false, false, 1):
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -191,7 +192,7 @@ public func call<M, T, R>(
/// The calls were made with the correct parameters, but didn't call enough times
case (_, false, true, _):
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -212,7 +213,7 @@ public func call<M, T, R>(
.max()
.defaulting(to: 0)
return PredicateResult(
return MatcherResult(
bool: false,
message: .expectedCustomValueTo(
expectedDescription,
@ -233,7 +234,7 @@ public func call<M, T, R>(
)
default:
return PredicateResult(
return MatcherResult(
bool: true,
message: .expectedCustomValueTo(
expectedDescription,

Loading…
Cancel
Save