diff --git a/Authorization/AuthorizationTests/AuthorizationMock.generated.swift b/Authorization/AuthorizationTests/AuthorizationMock.generated.swift index b6106d4d0..59adf71ce 100644 --- a/Authorization/AuthorizationTests/AuthorizationMock.generated.swift +++ b/Authorization/AuthorizationTests/AuthorizationMock.generated.swift @@ -93,23 +93,22 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { return __value } - @discardableResult - open func login(ssoToken: String) async throws -> Core.User { - addInvocation(.m_login__SSO__username_password(Parameter.value(`ssoToken`))) - let perform = methodPerformValue(.m_login__SSO__username_password(Parameter.value(`ssoToken`))) as? (String) -> Void - perform?(`ssoToken`) - var __value: User - do { - __value = try methodReturnValue(.m_login__SSO__username_password(Parameter.value(ssoToken))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for login(username: String, password: String). Use given") - Failure("Stub return value not specified for login(username: String, password: String). Use given") - } catch { - throw error - } - return __value + open func login(ssoToken: String) throws -> User { + addInvocation(.m_login__ssoToken_ssoToken(Parameter.value(`ssoToken`))) + let perform = methodPerformValue(.m_login__ssoToken_ssoToken(Parameter.value(`ssoToken`))) as? (String) -> Void + perform?(`ssoToken`) + var __value: User + do { + __value = try methodReturnValue(.m_login__ssoToken_ssoToken(Parameter.value(`ssoToken`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for login(ssoToken: String). Use given") + Failure("Stub return value not specified for login(ssoToken: String). Use given") + } catch { + throw error + } + return __value } - + open func resetPassword(email: String) throws -> ResetPassword { addInvocation(.m_resetPassword__email_email(Parameter.value(`email`))) let perform = methodPerformValue(.m_resetPassword__email_email(Parameter.value(`email`))) as? (String) -> Void @@ -190,8 +189,8 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { fileprivate enum MethodType { case m_login__username_usernamepassword_password(Parameter, Parameter) - case m_login__SSO__username_password(Parameter) case m_login__externalToken_externalTokenbackend_backend(Parameter, Parameter) + case m_login__ssoToken_ssoToken(Parameter) case m_resetPassword__email_email(Parameter) case m_getCookies__force_force(Parameter) case m_getRegistrationFields @@ -206,17 +205,17 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsPassword, rhs: rhsPassword, with: matcher), lhsPassword, rhsPassword, "password")) return Matcher.ComparisonResult(results) - case (.m_login__SSO__username_password(let lhsJwtToken), .m_login__SSO__username_password(let rhsJwtToken)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsJwtToken, rhs: rhsJwtToken, with: matcher), lhsJwtToken, rhsJwtToken, "jwtToken")) - return Matcher.ComparisonResult(results) - case (.m_login__externalToken_externalTokenbackend_backend(let lhsExternaltoken, let lhsBackend), .m_login__externalToken_externalTokenbackend_backend(let rhsExternaltoken, let rhsBackend)): var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsExternaltoken, rhs: rhsExternaltoken, with: matcher), lhsExternaltoken, rhsExternaltoken, "externalToken")) results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBackend, rhs: rhsBackend, with: matcher), lhsBackend, rhsBackend, "backend")) return Matcher.ComparisonResult(results) + case (.m_login__ssoToken_ssoToken(let lhsSsotoken), .m_login__ssoToken_ssoToken(let rhsSsotoken)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSsotoken, rhs: rhsSsotoken, with: matcher), lhsSsotoken, rhsSsotoken, "ssoToken")) + return Matcher.ComparisonResult(results) + case (.m_resetPassword__email_email(let lhsEmail), .m_resetPassword__email_email(let rhsEmail)): var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEmail, rhs: rhsEmail, with: matcher), lhsEmail, rhsEmail, "email")) @@ -246,8 +245,8 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { func intValue() -> Int { switch self { case let .m_login__username_usernamepassword_password(p0, p1): return p0.intValue + p1.intValue - case let .m_login__SSO__username_password(p0): return p0.intValue case let .m_login__externalToken_externalTokenbackend_backend(p0, p1): return p0.intValue + p1.intValue + case let .m_login__ssoToken_ssoToken(p0): return p0.intValue case let .m_resetPassword__email_email(p0): return p0.intValue case let .m_getCookies__force_force(p0): return p0.intValue case .m_getRegistrationFields: return 0 @@ -258,8 +257,8 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { func assertionName() -> String { switch self { case .m_login__username_usernamepassword_password: return ".login(username:password:)" - case .m_login__SSO__username_password: return ".loginSSO(username:password:)" case .m_login__externalToken_externalTokenbackend_backend: return ".login(externalToken:backend:)" + case .m_login__ssoToken_ssoToken: return ".login(ssoToken:)" case .m_resetPassword__email_email: return ".resetPassword(email:)" case .m_getCookies__force_force: return ".getCookies(force:)" case .m_getRegistrationFields: return ".getRegistrationFields()" @@ -286,9 +285,8 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { public static func login(externalToken: Parameter, backend: Parameter, willReturn: User...) -> MethodStub { return Given(method: .m_login__externalToken_externalTokenbackend_backend(`externalToken`, `backend`), products: willReturn.map({ StubProduct.return($0 as Any) })) } - @discardableResult - public static func ssoLogin(title: Parameter, willReturn: User...) -> MethodStub { - return Given(method: .m_login__SSO__username_password(`title`), products: willReturn.map({ StubProduct.return($0 as Any) })) + public static func login(ssoToken: Parameter, willReturn: User...) -> MethodStub { + return Given(method: .m_login__ssoToken_ssoToken(`ssoToken`), products: willReturn.map({ StubProduct.return($0 as Any) })) } public static func resetPassword(email: Parameter, willReturn: ResetPassword...) -> MethodStub { return Given(method: .m_resetPassword__email_email(`email`), products: willReturn.map({ StubProduct.return($0 as Any) })) @@ -326,6 +324,16 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { willProduce(stubber) return given } + public static func login(ssoToken: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_login__ssoToken_ssoToken(`ssoToken`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func login(ssoToken: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_login__ssoToken_ssoToken(`ssoToken`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (User).self) + willProduce(stubber) + return given + } public static func resetPassword(email: Parameter, willThrow: Error...) -> MethodStub { return Given(method: .m_resetPassword__email_email(`email`), products: willThrow.map({ StubProduct.throw($0) })) } @@ -382,10 +390,10 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { fileprivate var method: MethodType @discardableResult - public static func login(username: Parameter, password: Parameter) -> Verify { return Verify(method: .m_login__username_usernamepassword_password(`username`, `password`))} - public static func ssoLogin(title: Parameter) -> Verify { return Verify(method: .m_login__SSO__username_password(`title`))} + public static func login(username: Parameter, password: Parameter) -> Verify { return Verify(method: .m_login__username_usernamepassword_password(`username`, `password`))} @discardableResult public static func login(externalToken: Parameter, backend: Parameter) -> Verify { return Verify(method: .m_login__externalToken_externalTokenbackend_backend(`externalToken`, `backend`))} + public static func login(ssoToken: Parameter) -> Verify { return Verify(method: .m_login__ssoToken_ssoToken(`ssoToken`))} public static func resetPassword(email: Parameter) -> Verify { return Verify(method: .m_resetPassword__email_email(`email`))} public static func getCookies(force: Parameter) -> Verify { return Verify(method: .m_getCookies__force_force(`force`))} public static func getRegistrationFields() -> Verify { return Verify(method: .m_getRegistrationFields)} @@ -405,6 +413,9 @@ open class AuthInteractorProtocolMock: AuthInteractorProtocol, Mock { public static func login(externalToken: Parameter, backend: Parameter, perform: @escaping (String, String) -> Void) -> Perform { return Perform(method: .m_login__externalToken_externalTokenbackend_backend(`externalToken`, `backend`), performs: perform) } + public static func login(ssoToken: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_login__ssoToken_ssoToken(`ssoToken`), performs: perform) + } public static func resetPassword(email: Parameter, perform: @escaping (String) -> Void) -> Perform { return Perform(method: .m_resetPassword__email_email(`email`), performs: perform) } @@ -609,7 +620,6 @@ open class AuthorizationAnalyticsMock: AuthorizationAnalytics, Mock { fileprivate enum MethodType { case m_identify__id_idusername_usernameemail_email(Parameter, Parameter, Parameter) case m_userLogin__method_method(Parameter) - case m_ssoLogin__method_method(Parameter) case m_registerClicked case m_signInClicked case m_userSignInClicked @@ -669,7 +679,6 @@ open class AuthorizationAnalyticsMock: AuthorizationAnalytics, Mock { switch self { case let .m_identify__id_idusername_usernameemail_email(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue case let .m_userLogin__method_method(p0): return p0.intValue - case let .m_ssoLogin__method_method(p0): return p0.intValue case .m_registerClicked: return 0 case .m_signInClicked: return 0 case .m_userSignInClicked: return 0 @@ -685,7 +694,6 @@ open class AuthorizationAnalyticsMock: AuthorizationAnalytics, Mock { switch self { case .m_identify__id_idusername_usernameemail_email: return ".identify(id:username:email:)" case .m_userLogin__method_method: return ".userLogin(method:)" - case .m_ssoLogin__method_method: return ".ssoLogin(method:)" case .m_registerClicked: return ".registerClicked()" case .m_signInClicked: return ".signInClicked()" case .m_userSignInClicked: return ".userSignInClicked()" @@ -715,7 +723,6 @@ open class AuthorizationAnalyticsMock: AuthorizationAnalytics, Mock { public static func identify(id: Parameter, username: Parameter, email: Parameter) -> Verify { return Verify(method: .m_identify__id_idusername_usernameemail_email(`id`, `username`, `email`))} public static func userLogin(method: Parameter) -> Verify { return Verify(method: .m_userLogin__method_method(`method`))} - public static func ssoLogin(method: Parameter) -> Verify { return Verify(method: .m_ssoLogin__method_method(`method`))} public static func registerClicked() -> Verify { return Verify(method: .m_registerClicked)} public static func signInClicked() -> Verify { return Verify(method: .m_signInClicked)} public static func userSignInClicked() -> Verify { return Verify(method: .m_userSignInClicked)} @@ -962,11 +969,11 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { } open func showSSOWebBrowser(title: String) { - addInvocation(.m_showWebBrowser__SSO(Parameter.value(`title`))) - let perform = methodPerformValue(.m_showWebBrowser__SSO(Parameter.value(`title`))) as? (String) -> Void - perform?(`title`) + addInvocation(.m_showSSOWebBrowser__title_title(Parameter.value(`title`))) + let perform = methodPerformValue(.m_showSSOWebBrowser__title_title(Parameter.value(`title`))) as? (String) -> Void + perform?(`title`) } - + open func presentAlert(alertTitle: String, alertMessage: String, positiveAction: String, onCloseTapped: @escaping () -> Void, okTapped: @escaping () -> Void, type: AlertViewType) { addInvocation(.m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(Parameter.value(`alertTitle`), Parameter.value(`alertMessage`), Parameter.value(`positiveAction`), Parameter<() -> Void>.value(`onCloseTapped`), Parameter<() -> Void>.value(`okTapped`), Parameter.value(`type`))) let perform = methodPerformValue(.m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(Parameter.value(`alertTitle`), Parameter.value(`alertMessage`), Parameter.value(`positiveAction`), Parameter<() -> Void>.value(`onCloseTapped`), Parameter<() -> Void>.value(`okTapped`), Parameter.value(`type`))) as? (String, String, String, @escaping () -> Void, @escaping () -> Void, AlertViewType) -> Void @@ -1006,7 +1013,7 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { case m_showForgotPasswordScreen case m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(Parameter, Parameter) case m_showWebBrowser__title_titleurl_url(Parameter, Parameter) - case m_showWebBrowser__SSO(Parameter) + case m_showSSOWebBrowser__title_title(Parameter) case m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(Parameter, Parameter, Parameter, Parameter<() -> Void>, Parameter<() -> Void>, Parameter) case m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(Parameter, Parameter, Parameter, Parameter, Parameter, Parameter<() -> Void>, Parameter<() -> Void>, Parameter<() -> Void>) case m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(Parameter, Parameter, Parameter<(() -> Void)?>) @@ -1072,6 +1079,11 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUrl, rhs: rhsUrl, with: matcher), lhsUrl, rhsUrl, "url")) return Matcher.ComparisonResult(results) + case (.m_showSSOWebBrowser__title_title(let lhsTitle), .m_showSSOWebBrowser__title_title(let rhsTitle)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTitle, rhs: rhsTitle, with: matcher), lhsTitle, rhsTitle, "title")) + return Matcher.ComparisonResult(results) + case (.m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(let lhsAlerttitle, let lhsAlertmessage, let lhsPositiveaction, let lhsOnclosetapped, let lhsOktapped, let lhsType), .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(let rhsAlerttitle, let rhsAlertmessage, let rhsPositiveaction, let rhsOnclosetapped, let rhsOktapped, let rhsType)): var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAlerttitle, rhs: rhsAlerttitle, with: matcher), lhsAlerttitle, rhsAlerttitle, "alertTitle")) @@ -1126,7 +1138,7 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { case .m_showForgotPasswordScreen: return 0 case let .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(p0, p1): return p0.intValue + p1.intValue case let .m_showWebBrowser__title_titleurl_url(p0, p1): return p0.intValue + p1.intValue - case let .m_showWebBrowser__SSO(p0): return p0.intValue + case let .m_showSSOWebBrowser__title_title(p0): return p0.intValue case let .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(p0, p1, p2, p3, p4, p5): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + p4.intValue + p5.intValue case let .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(p0, p1, p2, p3, p4, p5, p6, p7): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + p4.intValue + p5.intValue + p6.intValue + p7.intValue case let .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue @@ -1148,7 +1160,7 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { case .m_showForgotPasswordScreen: return ".showForgotPasswordScreen()" case .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen: return ".showDiscoveryScreen(searchQuery:sourceScreen:)" case .m_showWebBrowser__title_titleurl_url: return ".showWebBrowser(title:url:)" - case .m_showWebBrowser__SSO: return ".showSSOWebBrowser(title:)" + case .m_showSSOWebBrowser__title_title: return ".showSSOWebBrowser(title:)" case .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type: return ".presentAlert(alertTitle:alertMessage:positiveAction:onCloseTapped:okTapped:type:)" case .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped: return ".presentAlert(alertTitle:alertMessage:nextSectionName:action:image:onCloseTapped:okTapped:nextSectionTapped:)" case .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion: return ".presentView(transitionStyle:view:completion:)" @@ -1184,6 +1196,7 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { public static func showForgotPasswordScreen() -> Verify { return Verify(method: .m_showForgotPasswordScreen)} public static func showDiscoveryScreen(searchQuery: Parameter, sourceScreen: Parameter) -> Verify { return Verify(method: .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(`searchQuery`, `sourceScreen`))} public static func showWebBrowser(title: Parameter, url: Parameter) -> Verify { return Verify(method: .m_showWebBrowser__title_titleurl_url(`title`, `url`))} + public static func showSSOWebBrowser(title: Parameter) -> Verify { return Verify(method: .m_showSSOWebBrowser__title_title(`title`))} public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, positiveAction: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, type: Parameter) -> Verify { return Verify(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(`alertTitle`, `alertMessage`, `positiveAction`, `onCloseTapped`, `okTapped`, `type`))} public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, nextSectionName: Parameter, action: Parameter, image: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, nextSectionTapped: Parameter<() -> Void>) -> Verify { return Verify(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(`alertTitle`, `alertMessage`, `nextSectionName`, `action`, `image`, `onCloseTapped`, `okTapped`, `nextSectionTapped`))} public static func presentView(transitionStyle: Parameter, view: Parameter, completion: Parameter<(() -> Void)?>) -> Verify { return Verify(method: .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(`transitionStyle`, `view`, `completion`))} @@ -1233,8 +1246,8 @@ open class AuthorizationRouterMock: AuthorizationRouter, Mock { public static func showWebBrowser(title: Parameter, url: Parameter, perform: @escaping (String, URL) -> Void) -> Perform { return Perform(method: .m_showWebBrowser__title_titleurl_url(`title`, `url`), performs: perform) } - public static func showSSOWebBrowser(title: Parameter, perform: @escaping (String, URL) -> Void) -> Perform { - return Perform(method: .m_showWebBrowser__SSO(`title`), performs: perform) + public static func showSSOWebBrowser(title: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_showSSOWebBrowser__title_title(`title`), performs: perform) } public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, positiveAction: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, type: Parameter, perform: @escaping (String, String, String, @escaping () -> Void, @escaping () -> Void, AlertViewType) -> Void) -> Perform { return Perform(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(`alertTitle`, `alertMessage`, `positiveAction`, `onCloseTapped`, `okTapped`, `type`), performs: perform) @@ -1435,14 +1448,14 @@ open class BaseRouterMock: BaseRouter, Mock { open func showWebBrowser(title: String, url: URL) { addInvocation(.m_showWebBrowser__title_titleurl_url(Parameter.value(`title`), Parameter.value(`url`))) - let perform = methodPerformValue(.m_showWebBrowser__title_titleurl_url(Parameter.value(`title`), Parameter.value(`url`))) as? (String, URL) -> Void - perform?(`title`, `url`) + let perform = methodPerformValue(.m_showWebBrowser__title_titleurl_url(Parameter.value(`title`), Parameter.value(`url`))) as? (String, URL) -> Void + perform?(`title`, `url`) } - + open func showSSOWebBrowser(title: String) { - addInvocation(.m_showWebBrowser__SSO(Parameter.value(`title`))) - let perform = methodPerformValue(.m_showWebBrowser__SSO(Parameter.value(`title`))) as? (String) -> Void - perform?(`title`) + addInvocation(.m_showSSOWebBrowser__title_title(Parameter.value(`title`))) + let perform = methodPerformValue(.m_showSSOWebBrowser__title_title(Parameter.value(`title`))) as? (String) -> Void + perform?(`title`) } open func presentAlert(alertTitle: String, alertMessage: String, positiveAction: String, onCloseTapped: @escaping () -> Void, okTapped: @escaping () -> Void, type: AlertViewType) { @@ -1483,7 +1496,7 @@ open class BaseRouterMock: BaseRouter, Mock { case m_showForgotPasswordScreen case m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(Parameter, Parameter) case m_showWebBrowser__title_titleurl_url(Parameter, Parameter) - case m_showWebBrowser__SSO(Parameter) + case m_showSSOWebBrowser__title_title(Parameter) case m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(Parameter, Parameter, Parameter, Parameter<() -> Void>, Parameter<() -> Void>, Parameter) case m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(Parameter, Parameter, Parameter, Parameter, Parameter, Parameter<() -> Void>, Parameter<() -> Void>, Parameter<() -> Void>) case m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(Parameter, Parameter, Parameter<(() -> Void)?>) @@ -1544,6 +1557,11 @@ open class BaseRouterMock: BaseRouter, Mock { results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUrl, rhs: rhsUrl, with: matcher), lhsUrl, rhsUrl, "url")) return Matcher.ComparisonResult(results) + case (.m_showSSOWebBrowser__title_title(let lhsTitle), .m_showSSOWebBrowser__title_title(let rhsTitle)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTitle, rhs: rhsTitle, with: matcher), lhsTitle, rhsTitle, "title")) + return Matcher.ComparisonResult(results) + case (.m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(let lhsAlerttitle, let lhsAlertmessage, let lhsPositiveaction, let lhsOnclosetapped, let lhsOktapped, let lhsType), .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(let rhsAlerttitle, let rhsAlertmessage, let rhsPositiveaction, let rhsOnclosetapped, let rhsOktapped, let rhsType)): var results: [Matcher.ParameterComparisonResult] = [] results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAlerttitle, rhs: rhsAlerttitle, with: matcher), lhsAlerttitle, rhsAlerttitle, "alertTitle")) @@ -1597,7 +1615,7 @@ open class BaseRouterMock: BaseRouter, Mock { case .m_showForgotPasswordScreen: return 0 case let .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(p0, p1): return p0.intValue + p1.intValue case let .m_showWebBrowser__title_titleurl_url(p0, p1): return p0.intValue + p1.intValue - case let .m_showWebBrowser__SSO(p0): return p0.intValue + case let .m_showSSOWebBrowser__title_title(p0): return p0.intValue case let .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(p0, p1, p2, p3, p4, p5): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + p4.intValue + p5.intValue case let .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(p0, p1, p2, p3, p4, p5, p6, p7): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + p4.intValue + p5.intValue + p6.intValue + p7.intValue case let .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue @@ -1618,7 +1636,7 @@ open class BaseRouterMock: BaseRouter, Mock { case .m_showForgotPasswordScreen: return ".showForgotPasswordScreen()" case .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen: return ".showDiscoveryScreen(searchQuery:sourceScreen:)" case .m_showWebBrowser__title_titleurl_url: return ".showWebBrowser(title:url:)" - case .m_showWebBrowser__SSO: return ".showSSOWebBrowser(title:)" + case .m_showSSOWebBrowser__title_title: return ".showSSOWebBrowser(title:)" case .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type: return ".presentAlert(alertTitle:alertMessage:positiveAction:onCloseTapped:okTapped:type:)" case .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped: return ".presentAlert(alertTitle:alertMessage:nextSectionName:action:image:onCloseTapped:okTapped:nextSectionTapped:)" case .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion: return ".presentView(transitionStyle:view:completion:)" @@ -1653,6 +1671,7 @@ open class BaseRouterMock: BaseRouter, Mock { public static func showForgotPasswordScreen() -> Verify { return Verify(method: .m_showForgotPasswordScreen)} public static func showDiscoveryScreen(searchQuery: Parameter, sourceScreen: Parameter) -> Verify { return Verify(method: .m_showDiscoveryScreen__searchQuery_searchQuerysourceScreen_sourceScreen(`searchQuery`, `sourceScreen`))} public static func showWebBrowser(title: Parameter, url: Parameter) -> Verify { return Verify(method: .m_showWebBrowser__title_titleurl_url(`title`, `url`))} + public static func showSSOWebBrowser(title: Parameter) -> Verify { return Verify(method: .m_showSSOWebBrowser__title_title(`title`))} public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, positiveAction: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, type: Parameter) -> Verify { return Verify(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(`alertTitle`, `alertMessage`, `positiveAction`, `onCloseTapped`, `okTapped`, `type`))} public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, nextSectionName: Parameter, action: Parameter, image: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, nextSectionTapped: Parameter<() -> Void>) -> Verify { return Verify(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagenextSectionName_nextSectionNameaction_actionimage_imageonCloseTapped_onCloseTappedokTapped_okTappednextSectionTapped_nextSectionTapped(`alertTitle`, `alertMessage`, `nextSectionName`, `action`, `image`, `onCloseTapped`, `okTapped`, `nextSectionTapped`))} public static func presentView(transitionStyle: Parameter, view: Parameter, completion: Parameter<(() -> Void)?>) -> Verify { return Verify(method: .m_presentView__transitionStyle_transitionStyleview_viewcompletion_completion(`transitionStyle`, `view`, `completion`))} @@ -1699,6 +1718,9 @@ open class BaseRouterMock: BaseRouter, Mock { public static func showWebBrowser(title: Parameter, url: Parameter, perform: @escaping (String, URL) -> Void) -> Perform { return Perform(method: .m_showWebBrowser__title_titleurl_url(`title`, `url`), performs: perform) } + public static func showSSOWebBrowser(title: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_showSSOWebBrowser__title_title(`title`), performs: perform) + } public static func presentAlert(alertTitle: Parameter, alertMessage: Parameter, positiveAction: Parameter, onCloseTapped: Parameter<() -> Void>, okTapped: Parameter<() -> Void>, type: Parameter, perform: @escaping (String, String, String, @escaping () -> Void, @escaping () -> Void, AlertViewType) -> Void) -> Perform { return Perform(method: .m_presentAlert__alertTitle_alertTitlealertMessage_alertMessagepositiveAction_positiveActiononCloseTapped_onCloseTappedokTapped_okTappedtype_type(`alertTitle`, `alertMessage`, `positiveAction`, `onCloseTapped`, `okTapped`, `type`), performs: perform) } @@ -1786,6 +1808,391 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Authorization/AuthorizationTests/Presentation/Login/SignInViewModelTests.swift b/Authorization/AuthorizationTests/Presentation/Login/SignInViewModelTests.swift index 371ac62b7..1435a61b9 100644 --- a/Authorization/AuthorizationTests/Presentation/Login/SignInViewModelTests.swift +++ b/Authorization/AuthorizationTests/Presentation/Login/SignInViewModelTests.swift @@ -109,11 +109,11 @@ final class SignInViewModelTests: XCTestCase { ) let user = User(id: 1, username: "username", email: "edxUser@edx.com", name: "Name", userAvatar: "") - Given(interactor, .ssoLogin(title: .any, willReturn: user)) + Given(interactor, .login(ssoToken: .any, willReturn: user)) await viewModel.ssoLogin(title: "Riyadah") - Verify(interactor, 1, .ssoLogin(title: .any)) + Verify(interactor, 1, .login(ssoToken: .any)) Verify(router, 1, .showMainOrWhatsNewScreen(sourceScreen: .any)) XCTAssertEqual(viewModel.errorMessage, nil) diff --git a/Core/Core/Configuration/Config/Config.swift b/Core/Core/Configuration/Config/Config.swift index 8c0cd2d18..adad33a0d 100644 --- a/Core/Core/Configuration/Config/Config.swift +++ b/Core/Core/Configuration/Config/Config.swift @@ -7,6 +7,7 @@ import Foundation +//sourcery: AutoMockable public protocol ConfigProtocol { var baseURL: URL { get } var baseSSOURL: URL { get } diff --git a/Core/Core/Domain/Model/CourseForSync.swift b/Core/Core/Domain/Model/CourseForSync.swift index d3d7af491..5f3a6c343 100644 --- a/Core/Core/Domain/Model/CourseForSync.swift +++ b/Core/Core/Domain/Model/CourseForSync.swift @@ -41,3 +41,11 @@ extension DataLayer.EnrollmentsStatus { } } +extension CourseForSync: Equatable { + public static func == (lhs: CourseForSync, rhs: CourseForSync) -> Bool { + return lhs.courseID == rhs.courseID && + lhs.name == rhs.name && + lhs.synced == rhs.synced && + lhs.recentlyActive == rhs.recentlyActive + } +} diff --git a/Core/Core/View/Base/CalendarManagerProtocol.swift b/Core/Core/View/Base/CalendarManagerProtocol.swift index ef7fdcb3e..152c0dc21 100644 --- a/Core/Core/View/Base/CalendarManagerProtocol.swift +++ b/Core/Core/View/Base/CalendarManagerProtocol.swift @@ -7,6 +7,7 @@ import Foundation +//sourcery: AutoMockable public protocol CalendarManagerProtocol { func createCalendarIfNeeded() func filterCoursesBySelected(fetchedCourses: [CourseForSync]) async -> [CourseForSync] diff --git a/Core/CoreTests/CoreMock.generated.swift b/Core/CoreTests/CoreMock.generated.swift index 4ec87ace6..3fbb5c626 100644 --- a/Core/CoreTests/CoreMock.generated.swift +++ b/Core/CoreTests/CoreMock.generated.swift @@ -977,6 +977,899 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - ConfigProtocol + +open class ConfigProtocolMock: ConfigProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? + + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? + + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? + + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? + + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? + + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? + + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? + + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? + + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? + + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? + + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? + + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? + + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? + + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? + + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? + + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? + + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? + + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? + + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? + + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? + + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? + + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Core/CoreTests/DownloadManager/DownloadManagerTests.swift b/Core/CoreTests/DownloadManager/DownloadManagerTests.swift index 1b6d03b62..67e0aa644 100644 --- a/Core/CoreTests/DownloadManager/DownloadManagerTests.swift +++ b/Core/CoreTests/DownloadManager/DownloadManagerTests.swift @@ -100,6 +100,9 @@ final class DownloadManagerTests: XCTestCase { // When try await downloadManager.resumeDownloading() + // Wait a bit for async operations to complete + try? await Task.sleep(nanoseconds: 100_000_000) + // Then Verify(persistence, 2, .nextBlockForDownloading()) XCTAssertEqual(downloadManager.currentDownloadTask?.id, mockTask.id) diff --git a/Course/CourseTests/CourseMock.generated.swift b/Course/CourseTests/CourseMock.generated.swift index ca2964927..9033a7383 100644 --- a/Course/CourseTests/CourseMock.generated.swift +++ b/Course/CourseTests/CourseMock.generated.swift @@ -978,6 +978,899 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - ConfigProtocol + +open class ConfigProtocolMock: ConfigProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? + + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? + + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? + + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? + + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? + + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? + + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? + + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? + + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? + + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? + + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? + + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? + + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? + + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? + + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? + + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? + + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? + + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? + + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? + + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? + + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? + + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Dashboard/Dashboard.xcodeproj/project.pbxproj b/Dashboard/Dashboard.xcodeproj/project.pbxproj index 625c0d2f0..d6aa32efb 100644 --- a/Dashboard/Dashboard.xcodeproj/project.pbxproj +++ b/Dashboard/Dashboard.xcodeproj/project.pbxproj @@ -36,6 +36,8 @@ 214DA1AADABC7BF4FB8EA1D7 /* Pods_App_Dashboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B008B2F0762EF35CADE3DD4 /* Pods_App_Dashboard.framework */; }; 97E7DF0B2B7A3EAF00A2A09B /* CourseEnrollmentsMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97E7DF0A2B7A3EAF00A2A09B /* CourseEnrollmentsMock.swift */; }; 9AD4A6A1AAF97092CF457FE2 /* Pods_App_Dashboard_DashboardTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 22905947A936093AD23D4CF8 /* Pods_App_Dashboard_DashboardTests.framework */; }; + CE1735062CD2552A00F9606A /* PrimaryCourseDashboardViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1735052CD2552A00F9606A /* PrimaryCourseDashboardViewModelTests.swift */; }; + CE17350A2CD26CB500F9606A /* AllCoursesViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1735092CD26CB500F9606A /* AllCoursesViewModelTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -91,6 +93,8 @@ 97E7DF0A2B7A3EAF00A2A09B /* CourseEnrollmentsMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseEnrollmentsMock.swift; sourceTree = ""; }; BBABB135366FFB1DAEFA0D16 /* Pods-App-Dashboard-DashboardTests.debugprod.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Dashboard-DashboardTests.debugprod.xcconfig"; path = "Target Support Files/Pods-App-Dashboard-DashboardTests/Pods-App-Dashboard-DashboardTests.debugprod.xcconfig"; sourceTree = ""; }; CCF4C665AD91B6B96F6A11DF /* Pods-App-Dashboard-DashboardTests.debugdev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Dashboard-DashboardTests.debugdev.xcconfig"; path = "Target Support Files/Pods-App-Dashboard-DashboardTests/Pods-App-Dashboard-DashboardTests.debugdev.xcconfig"; sourceTree = ""; }; + CE1735052CD2552A00F9606A /* PrimaryCourseDashboardViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryCourseDashboardViewModelTests.swift; sourceTree = ""; }; + CE1735092CD26CB500F9606A /* AllCoursesViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllCoursesViewModelTests.swift; sourceTree = ""; }; DE6CF4F983BBF52606807F9A /* Pods-App-Dashboard-DashboardTests.debugstage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Dashboard-DashboardTests.debugstage.xcconfig"; path = "Target Support Files/Pods-App-Dashboard-DashboardTests/Pods-App-Dashboard-DashboardTests.debugstage.xcconfig"; sourceTree = ""; }; E36D702D7E3F9A8B3303AD0A /* Pods-App-Dashboard-DashboardTests.releasedev.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Dashboard-DashboardTests.releasedev.xcconfig"; path = "Target Support Files/Pods-App-Dashboard-DashboardTests/Pods-App-Dashboard-DashboardTests.releasedev.xcconfig"; sourceTree = ""; }; E5B672C28C8F9279BB4E5C9B /* Pods-App-Dashboard.releasestage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Dashboard.releasestage.xcconfig"; path = "Target Support Files/Pods-App-Dashboard/Pods-App-Dashboard.releasestage.xcconfig"; sourceTree = ""; }; @@ -237,6 +241,8 @@ 0766DFD2299AD99B00EBEF6A /* Presentation */ = { isa = PBXGroup; children = ( + CE1735092CD26CB500F9606A /* AllCoursesViewModelTests.swift */, + CE1735052CD2552A00F9606A /* PrimaryCourseDashboardViewModelTests.swift */, 02A9A90A2978194100B55797 /* DashboardViewModelTests.swift */, ); path = Presentation; @@ -483,7 +489,9 @@ buildActionMask = 2147483647; files = ( 02A9A90B2978194100B55797 /* DashboardViewModelTests.swift in Sources */, + CE17350A2CD26CB500F9606A /* AllCoursesViewModelTests.swift in Sources */, 02A9A92929781A4D00B55797 /* DashboardMock.generated.swift in Sources */, + CE1735062CD2552A00F9606A /* PrimaryCourseDashboardViewModelTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Dashboard/DashboardTests/DashboardMock.generated.swift b/Dashboard/DashboardTests/DashboardMock.generated.swift index a63173694..f0dcb32d9 100644 --- a/Dashboard/DashboardTests/DashboardMock.generated.swift +++ b/Dashboard/DashboardTests/DashboardMock.generated.swift @@ -978,6 +978,899 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - ConfigProtocol + +open class ConfigProtocolMock: ConfigProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? + + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? + + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? + + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? + + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? + + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? + + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? + + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? + + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? + + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? + + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? + + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? + + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? + + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? + + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? + + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? + + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? + + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? + + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? + + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? + + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? + + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift b/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift new file mode 100644 index 000000000..625120e66 --- /dev/null +++ b/Dashboard/DashboardTests/Presentation/AllCoursesViewModelTests.swift @@ -0,0 +1,219 @@ +// +// AllCoursesViewModelTests.swift +// Dashboard +// +// Created by Ivan Stepanok on 30.10.2024. +// + + +import SwiftyMocky +import XCTest +@testable import Core +@testable import Dashboard +import Combine +import SwiftUI + +final class AllCoursesViewModelTests: XCTestCase { + + var interactor: DashboardInteractorProtocolMock! + var connectivity: ConnectivityProtocolMock! + var analytics: DashboardAnalyticsMock! + var storage: CoreStorageMock! + + override func setUp() { + super.setUp() + interactor = DashboardInteractorProtocolMock() + connectivity = ConnectivityProtocolMock() + analytics = DashboardAnalyticsMock() + storage = CoreStorageMock() + } + + let mockEnrollment = PrimaryEnrollment( + primaryCourse: PrimaryCourse.init( + name: "Primary Course", + org: "OpenEdX", + courseID: "1", + hasAccess: true, + courseStart: Date(), + courseEnd: nil, + courseBanner: "https://example.com/banner.jpg", + futureAssignments: [], + pastAssignments: [], + progressEarned: 0, + progressPossible: 1, + lastVisitedBlockID: nil, + resumeTitle: nil + ), + courses: [ + CourseItem.init( + name: "Course", + org: "OpenEdX", + shortDescription: "short description", + imageURL: "https://examlpe.com/image.jpg", + hasAccess: true, + courseStart: nil, + courseEnd: nil, + enrollmentStart: nil, + enrollmentEnd: nil, + courseID: "2", + numPages: 1, + coursesCount: 3, + progressEarned: 0, + progressPossible: 2 + ), + CourseItem.init( + name: "Course", + org: "OpenEdX", + shortDescription: "short description", + imageURL: "https://examlpe.com/image.jpg", + hasAccess: true, + courseStart: nil, + courseEnd: nil, + enrollmentStart: nil, + enrollmentEnd: nil, + courseID: "3", + numPages: 1, + coursesCount: 3, + progressEarned: 0, + progressPossible: 2 + ), + CourseItem.init( + name: "Course", + org: "OpenEdX", + shortDescription: "short description", + imageURL: "https://examlpe.com/image.jpg", + hasAccess: true, + courseStart: nil, + courseEnd: nil, + enrollmentStart: nil, + enrollmentEnd: nil, + courseID: "4", + numPages: 1, + coursesCount: 3, + progressEarned: 0, + progressPossible: 2 + ) + ], + totalPages: 2, + count: 1 + ) + + func testGetCoursesSuccess() async throws { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + Given(interactor, .getAllCourses(filteredBy: .any, page: .any, willReturn: mockEnrollment)) + + // When + await viewModel.getCourses(page: 1) + + // Then + Verify(interactor, 1, .getAllCourses(filteredBy: .any, page: .value(1))) + XCTAssertEqual(viewModel.myEnrollments?.courses.count, 3) + XCTAssertEqual(viewModel.nextPage, 2) + XCTAssertEqual(viewModel.totalPages, 2) + XCTAssertFalse(viewModel.fetchInProgress) + XCTAssertFalse(viewModel.showError) + } + + func testGetCoursesWithPagination() async throws { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + Given(interactor, .getAllCourses(filteredBy: .any, page: .any, willReturn: mockEnrollment)) + + // When + await viewModel.getCourses(page: 1) + await viewModel.getCourses(page: 2) + + // Then + Verify(interactor, 2, .getAllCourses(filteredBy: .any, page: .any)) + XCTAssertEqual(viewModel.nextPage, 3) + } + + func testGetCoursesNoCachedDataError() async throws { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + Given(interactor, .getAllCourses(filteredBy: .any, page: .any, willThrow: NoCachedDataError())) + + // When + await viewModel.getCourses(page: 1) + + // Then + XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.noCachedData) + XCTAssertTrue(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testGetCoursesUnknownError() async throws { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + Given(interactor, .getAllCourses(filteredBy: .any, page: .any, willThrow: NSError())) + + // When + await viewModel.getCourses(page: 1) + + // Then + XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.unknownError) + XCTAssertTrue(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testGetMyCoursesPagination() async { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + Given(interactor, .getAllCourses(filteredBy: .any, page: .any, willReturn: mockEnrollment)) + + // When + await viewModel.getCourses(page: 1) + await viewModel.getMyCoursesPagination(index: 0) + await viewModel.getMyCoursesPagination(index: mockEnrollment.courses.count - 3) + + // Then + Verify(interactor, 2, .getAllCourses(filteredBy: .any, page: .any)) + } + + func testTrackDashboardCourseClicked() { + // Given + let viewModel = AllCoursesViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + storage: storage + ) + + // When + viewModel.trackDashboardCourseClicked(courseID: "test-id", courseName: "Test Course") + + // Then + Verify(analytics, 1, .dashboardCourseClicked(courseID: .value("test-id"), courseName: .value("Test Course"))) + } +} diff --git a/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift b/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift new file mode 100644 index 000000000..c4083e705 --- /dev/null +++ b/Dashboard/DashboardTests/Presentation/PrimaryCourseDashboardViewModelTests.swift @@ -0,0 +1,213 @@ +// +// PrimaryCourseDashboardViewModelTests.swift +// Dashboard +// +// Created by Ivan Stepanok on 30.10.2024. +// + + +import SwiftyMocky +import XCTest +@testable import Core +@testable import Dashboard +import Combine +import SwiftUI + +final class PrimaryCourseDashboardViewModelTests: XCTestCase { + + var interactor: DashboardInteractorProtocolMock! + var connectivity: ConnectivityProtocolMock! + var analytics: DashboardAnalyticsMock! + var storage: CoreStorageMock! + var config: ConfigProtocolMock! + + override func setUp() { + super.setUp() + interactor = DashboardInteractorProtocolMock() + connectivity = ConnectivityProtocolMock() + analytics = DashboardAnalyticsMock() + storage = CoreStorageMock() + config = ConfigProtocolMock() + interactor = DashboardInteractorProtocolMock() + } + + let enrollment = PrimaryEnrollment( + primaryCourse: PrimaryCourse.init( + name: "Primary Course", + org: "OpenEdX", + courseID: "1", + hasAccess: true, + courseStart: Date(), + courseEnd: nil, + courseBanner: "https://example.com/banner.jpg", + futureAssignments: [], + pastAssignments: [], + progressEarned: 0, + progressPossible: 1, + lastVisitedBlockID: nil, + resumeTitle: nil + ), + courses: [ + CourseItem.init( + name: "Course", + org: "OpenEdX", + shortDescription: "short description", + imageURL: "https://examlpe.com/image.jpg", + hasAccess: true, + courseStart: nil, + courseEnd: nil, + enrollmentStart: nil, + enrollmentEnd: nil, + courseID: "2", + numPages: 1, + coursesCount: 3, + progressEarned: 0, + progressPossible: 2 + ) + ], + totalPages: 1, + count: 1 + ) + + func testGetEnrollmentsSuccess() async throws { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(interactor, .getPrimaryEnrollment(pageSize: .any, willReturn: enrollment)) + + // When + await viewModel.getEnrollments() + + // Then + Verify(interactor, 1, .getPrimaryEnrollment(pageSize: .value(UIDevice.current.userInterfaceIdiom == .pad ? 7 : 5))) + XCTAssertEqual(viewModel.enrollments, enrollment) + XCTAssertNil(viewModel.errorMessage) + XCTAssertFalse(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testGetEnrollmentsOfflineSuccess() async throws { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + Given(connectivity, .isInternetAvaliable(getter: false)) + Given(interactor, .getPrimaryEnrollmentOffline(willReturn: enrollment)) + + // When + await viewModel.getEnrollments() + + // Then + Verify(interactor, 1, .getPrimaryEnrollmentOffline()) + XCTAssertEqual(viewModel.enrollments, enrollment) + XCTAssertNil(viewModel.errorMessage) + XCTAssertFalse(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testGetEnrollmentsNoCacheError() async throws { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(interactor, .getPrimaryEnrollment(pageSize: .any, willThrow: NoCachedDataError())) + + // When + await viewModel.getEnrollments() + + // Then + Verify(interactor, 1, .getPrimaryEnrollment(pageSize: .value(UIDevice.current.userInterfaceIdiom == .pad ? 7 : 5))) + XCTAssertNil(viewModel.enrollments) + XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.noCachedData) + XCTAssertTrue(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testGetEnrollmentsUnknownError() async throws { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(interactor, .getPrimaryEnrollment(pageSize: .any, willThrow: NSError())) + + // When + await viewModel.getEnrollments() + + // Then + Verify(interactor, 1, .getPrimaryEnrollment(pageSize: .value(UIDevice.current.userInterfaceIdiom == .pad ? 7 : 5))) + XCTAssertNil(viewModel.enrollments) + XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.unknownError) + XCTAssertTrue(viewModel.showError) + XCTAssertFalse(viewModel.fetchInProgress) + } + + func testTrackDashboardCourseClicked() { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + let courseID = "test-course-id" + let courseName = "Test Course" + + // When + viewModel.trackDashboardCourseClicked(courseID: courseID, courseName: courseName) + + // Then + Verify(analytics, 1, .dashboardCourseClicked(courseID: .value(courseID), courseName: .value(courseName))) + } + + func testNotificationCenterSubscriptions() async { + // Given + let viewModel = PrimaryCourseDashboardViewModel( + interactor: interactor, + connectivity: connectivity, + analytics: analytics, + config: config, + storage: storage + ) + + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(interactor, .getPrimaryEnrollment(pageSize: .any, willReturn: enrollment)) + + // When + NotificationCenter.default.post(name: .onCourseEnrolled, object: nil) + NotificationCenter.default.post(name: .onblockCompletionRequested, object: nil) + NotificationCenter.default.post(name: .refreshEnrollments, object: nil) + + // Wait a bit for async operations to complete + try? await Task.sleep(nanoseconds: 100_000_000) + + // Then + // Verify that getEnrollments was called multiple times due to notifications + Verify(interactor, .getPrimaryEnrollment(pageSize: .any)) + } +} diff --git a/Discovery/DiscoveryTests/DiscoveryMock.generated.swift b/Discovery/DiscoveryTests/DiscoveryMock.generated.swift index d1f2c7a15..21cd06ec0 100644 --- a/Discovery/DiscoveryTests/DiscoveryMock.generated.swift +++ b/Discovery/DiscoveryTests/DiscoveryMock.generated.swift @@ -978,6 +978,899 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - ConfigProtocol + +open class ConfigProtocolMock: ConfigProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? + + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? + + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? + + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? + + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? + + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? + + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? + + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? + + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? + + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? + + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? + + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? + + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? + + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? + + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? + + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? + + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? + + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? + + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? + + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? + + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? + + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Discussion/DiscussionTests/DiscussionMock.generated.swift b/Discussion/DiscussionTests/DiscussionMock.generated.swift index 1f1237234..e3a6b6361 100644 --- a/Discussion/DiscussionTests/DiscussionMock.generated.swift +++ b/Discussion/DiscussionTests/DiscussionMock.generated.swift @@ -978,6 +978,899 @@ open class BaseRouterMock: BaseRouter, Mock { } } +// MARK: - CalendarManagerProtocol + +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } + + + fileprivate enum MethodType { + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue + } + } + func assertionName() -> String { + switch self { + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - ConfigProtocol + +open class ConfigProtocolMock: ConfigProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? + + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? + + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? + + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? + + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? + + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? + + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? + + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? + + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? + + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? + + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? + + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? + + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? + + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? + + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? + + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? + + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? + + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? + + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? + + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? + + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? + + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - ConnectivityProtocol open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { diff --git a/Profile/Profile.xcodeproj/project.pbxproj b/Profile/Profile.xcodeproj/project.pbxproj index 1562e19f0..cdced1def 100644 --- a/Profile/Profile.xcodeproj/project.pbxproj +++ b/Profile/Profile.xcodeproj/project.pbxproj @@ -58,6 +58,8 @@ 0796C8C929B7905300444B05 /* ProfileBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0796C8C829B7905300444B05 /* ProfileBottomSheet.swift */; }; 25B36FF48C1307888A3890DA /* Pods_App_Profile.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEA369C38362C1A91A012F70 /* Pods_App_Profile.framework */; }; BAD9CA3F2B29BF5C00DE790A /* ProfileSupportInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAD9CA3E2B29BF5C00DE790A /* ProfileSupportInfoView.swift */; }; + CE1735042CD23D7A00F9606A /* DatesAndCalendarViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1735032CD23D7A00F9606A /* DatesAndCalendarViewModelTests.swift */; }; + CE961F032CD163FD00799B9F /* CalendarManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE961F022CD163FD00799B9F /* CalendarManagerTests.swift */; }; E8264C634DD8AD314ECE8905 /* Pods_App_Profile_ProfileTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C85ADF87135E03275A980E07 /* Pods_App_Profile_ProfileTests.framework */; }; /* End PBXBuildFile section */ @@ -139,6 +141,8 @@ BAD9CA3E2B29BF5C00DE790A /* ProfileSupportInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileSupportInfoView.swift; sourceTree = ""; }; BEA369C38362C1A91A012F70 /* Pods_App_Profile.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App_Profile.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C85ADF87135E03275A980E07 /* Pods_App_Profile_ProfileTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_App_Profile_ProfileTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CE1735032CD23D7A00F9606A /* DatesAndCalendarViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatesAndCalendarViewModelTests.swift; sourceTree = ""; }; + CE961F022CD163FD00799B9F /* CalendarManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarManagerTests.swift; sourceTree = ""; }; F52EFE7DC07BE68B9A302DAF /* Pods-App-Profile.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Profile.debug.xcconfig"; path = "Target Support Files/Pods-App-Profile/Pods-App-Profile.debug.xcconfig"; sourceTree = ""; }; FB33709D5DBACDEA33BD016F /* Pods-App-Profile-ProfileTests.debugstage.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-App-Profile-ProfileTests.debugstage.xcconfig"; path = "Target Support Files/Pods-App-Profile-ProfileTests/Pods-App-Profile-ProfileTests.debugstage.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -375,6 +379,8 @@ 02A9A91B2978194A00B55797 /* ProfileTests */ = { isa = PBXGroup; children = ( + CE961F022CD163FD00799B9F /* CalendarManagerTests.swift */, + CE1735032CD23D7A00F9606A /* DatesAndCalendarViewModelTests.swift */, 0766DFD3299AD9D800EBEF6A /* Presentation */, 02A9A92A29781A6300B55797 /* ProfileMock.generated.swift */, ); @@ -706,8 +712,10 @@ buildActionMask = 2147483647; files = ( 02A9A92B29781A6300B55797 /* ProfileMock.generated.swift in Sources */, + CE1735042CD23D7A00F9606A /* DatesAndCalendarViewModelTests.swift in Sources */, 02A4833329B7710A00D33F33 /* DeleteAccountViewModelTests.swift in Sources */, 02FE9A802BC707D500B3C206 /* SettingsViewModelTests.swift in Sources */, + CE961F032CD163FD00799B9F /* CalendarManagerTests.swift in Sources */, 02A9A91D2978194A00B55797 /* ProfileViewModelTests.swift in Sources */, 020102D129784B3100BBF80C /* EditProfileViewModelTests.swift in Sources */, ); diff --git a/Profile/Profile/Data/Persistence/ProfilePersistenceProtocol.swift b/Profile/Profile/Data/Persistence/ProfilePersistenceProtocol.swift index 3e26799bd..e87f1aa19 100644 --- a/Profile/Profile/Data/Persistence/ProfilePersistenceProtocol.swift +++ b/Profile/Profile/Data/Persistence/ProfilePersistenceProtocol.swift @@ -8,6 +8,7 @@ import CoreData import Core +//sourcery: AutoMockable public protocol ProfilePersistenceProtocol { func getCourseState(courseID: String) -> CourseCalendarState? func getAllCourseStates() -> [CourseCalendarState] diff --git a/Profile/Profile/Data/ProfileStorage.swift b/Profile/Profile/Data/ProfileStorage.swift index 88e8fe48b..68347091f 100644 --- a/Profile/Profile/Data/ProfileStorage.swift +++ b/Profile/Profile/Data/ProfileStorage.swift @@ -9,6 +9,7 @@ import Foundation import Core import UIKit +//sourcery: AutoMockable public protocol ProfileStorage { var userProfile: DataLayer.UserProfile? {get set} var useRelativeDates: Bool {get set} diff --git a/Profile/Profile/Presentation/DatesAndCalendar/DatesAndCalendarViewModel.swift b/Profile/Profile/Presentation/DatesAndCalendar/DatesAndCalendarViewModel.swift index 66be4d491..3201e2a1f 100644 --- a/Profile/Profile/Presentation/DatesAndCalendar/DatesAndCalendarViewModel.swift +++ b/Profile/Profile/Presentation/DatesAndCalendar/DatesAndCalendarViewModel.swift @@ -39,8 +39,8 @@ public class DatesAndCalendarViewModel: ObservableObject { private var coursesForSyncBeforeChanges = [CourseForSync]() - private var coursesForDeleting = [CourseForSync]() - private var coursesForAdding = [CourseForSync]() + private(set) var coursesForDeleting = [CourseForSync]() + private(set) var coursesForAdding = [CourseForSync]() @Published var synced: Bool = true @Published var hideInactiveCourses: Bool = false diff --git a/Profile/ProfileTests/CalendarManagerTests.swift b/Profile/ProfileTests/CalendarManagerTests.swift new file mode 100644 index 000000000..de245eaea --- /dev/null +++ b/Profile/ProfileTests/CalendarManagerTests.swift @@ -0,0 +1,290 @@ +// +// CalendarManagerTests.swift +// Profile +// +// Created by Ivan Stepanok on 29.10.2024. +// + + +import SwiftyMocky +import XCTest +import EventKit +@testable import Profile +@testable import Core +import Theme +import SwiftUICore + +final class CalendarManagerTests: XCTestCase { + + func testCourseStatusSynced() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + let states = [CourseCalendarState(courseID: "course-1", checksum: "checksum-1")] + Given(persistence, .getAllCourseStates(willReturn: states)) + + let status = manager.courseStatus(courseID: "course-1") + + Verify(persistence, 1, .getAllCourseStates()) + XCTAssertEqual(status, .synced) + } + + func testCourseStatusOffline() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + let states = [CourseCalendarState(courseID: "course-2", checksum: "checksum-2")] + Given(persistence, .getAllCourseStates(willReturn: states)) + + let status = manager.courseStatus(courseID: "course-1") + + Verify(persistence, 1, .getAllCourseStates()) + XCTAssertEqual(status, .offline) + } + + func testIsDatesChanged() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + let state = CourseCalendarState(courseID: "course-1", checksum: "old-checksum") + Given(persistence, .getCourseState(courseID: .value("course-1"), willReturn: state)) + + let changed = manager.isDatesChanged(courseID: "course-1", checksum: "new-checksum") + + Verify(persistence, 1, .getCourseState(courseID: .value("course-1"))) + XCTAssertTrue(changed) + } + + func testIsDatesNotChanged() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + let state = CourseCalendarState(courseID: "course-1", checksum: "same-checksum") + Given(persistence, .getCourseState(courseID: .value("course-1"), willReturn: state)) + + let changed = manager.isDatesChanged(courseID: "course-1", checksum: "same-checksum") + + Verify(persistence, 1, .getCourseState(courseID: .value("course-1"))) + XCTAssertFalse(changed) + } + + func testClearAllData() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + // Setup initial values + profileStorage.firstCalendarUpdate = true + profileStorage.hideInactiveCourses = true + profileStorage.lastCalendarName = "Test Calendar" + profileStorage.calendarSettings = CalendarSettings( + colorSelection: "accent", + calendarName: "Test Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + profileStorage.lastCalendarUpdateDate = Date() + + // Verify initial values are set + XCTAssertTrue(profileStorage.firstCalendarUpdate ?? false) + XCTAssertTrue(profileStorage.hideInactiveCourses ?? false) + XCTAssertNotNil(profileStorage.lastCalendarName) + XCTAssertNotNil(profileStorage.calendarSettings) + XCTAssertNotNil(profileStorage.lastCalendarUpdateDate) + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + manager.clearAllData(removeCalendar: true) + + // Verify persistence method was called + Verify(persistence, 1, .deleteAllCourseStatesAndEvents()) + + // Verify all values were cleared + XCTAssertEqual(profileStorage.firstCalendarUpdate, false) + XCTAssertNil(profileStorage.hideInactiveCourses) + XCTAssertNil(profileStorage.lastCalendarName) + XCTAssertNil(profileStorage.calendarSettings) + XCTAssertNil(profileStorage.lastCalendarUpdateDate) + } + + func testFilterCoursesBySelected() async throws { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + let states = [ + CourseCalendarState(courseID: "course-1", checksum: "checksum-1"), + CourseCalendarState(courseID: "course-2", checksum: "checksum-2"), + CourseCalendarState(courseID: "course-3", checksum: "checksum-3") + ] + + let fetchedCourses = [ + CourseForSync( + id: UUID(), + courseID: "course-1", + name: "Course 1", + synced: true, + recentlyActive: true + ), + CourseForSync( + id: UUID(), + courseID: "course-2", + name: "Course 2", + synced: true, + recentlyActive: false + ), + CourseForSync( + id: UUID(), + courseID: "course-4", + name: "Course 4", + synced: false, + recentlyActive: true + ) + ] + + // Setup mocks + Given(persistence, .getAllCourseStates(willReturn: states)) + Given(persistence, .getCourseCalendarEvents(for: .any, willReturn: [])) + Given(persistence, .getCourseState(courseID: .any, willReturn: nil)) +// Given(persistence, .removeCourseCalendarEvents(for: .any, willProduce: { _ in })) + + // Execute filtering + let filteredCourses = await manager.filterCoursesBySelected(fetchedCourses: fetchedCourses) + + // Verify calls + Verify(persistence, 1, .getAllCourseStates()) + + // Verify course-3 was removed (exists in states but not in fetched) + Verify(persistence, 1, .getCourseCalendarEvents(for: .value("course-3"))) + Verify(persistence, 1, .removeCourseCalendarEvents(for: .value("course-3"))) + + // Verify course-2 was removed (inactive) + Verify(persistence, 1, .getCourseCalendarEvents(for: .value("course-2"))) + Verify(persistence, 1, .removeCourseCalendarEvents(for: .value("course-2"))) + + // Verify results + XCTAssertEqual(filteredCourses.count, 1) + XCTAssertEqual(filteredCourses.first?.courseID, "course-1") + XCTAssertEqual(filteredCourses.first?.name, "Course 1") + XCTAssertTrue(filteredCourses.first?.synced ?? false) + XCTAssertTrue(filteredCourses.first?.recentlyActive ?? false) + } + + func testFilterCoursesBySelectedEmptyStates() async { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + Given(persistence, .getAllCourseStates(willReturn: [])) + + let fetchedCourses = [ + CourseForSync( + id: UUID(), + courseID: "course-1", + name: "Course 1", + synced: true, + recentlyActive: true + ), + CourseForSync( + id: UUID(), + courseID: "course-2", + name: "Course 2", + synced: true, + recentlyActive: false + ) + ] + + let filteredCourses = await manager.filterCoursesBySelected(fetchedCourses: fetchedCourses) + + Verify(persistence, 1, .getAllCourseStates()) + XCTAssertEqual(filteredCourses, fetchedCourses) + } + + func testCalendarNameFromSettings() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let settings = CalendarSettings( + colorSelection: "accent", + calendarName: "Test Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + Given(profileStorage, .calendarSettings(getter: settings)) + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + XCTAssertEqual(manager.calendarName, "Test Calendar") + } + + func testColorSelectionFromSettings() { + let persistence = ProfilePersistenceProtocolMock() + let interactor = ProfileInteractorProtocolMock() + let profileStorage = ProfileStorageMock() + + let settings = CalendarSettings( + colorSelection: "accent", + calendarName: "Test Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + Given(profileStorage, .calendarSettings(getter: settings)) + + let manager = CalendarManager( + persistence: persistence, + interactor: interactor, + profileStorage: profileStorage + ) + + XCTAssertEqual(manager.colorSelection?.color, Color.accentColor) + } +} diff --git a/Profile/ProfileTests/DatesAndCalendarViewModelTests.swift b/Profile/ProfileTests/DatesAndCalendarViewModelTests.swift new file mode 100644 index 000000000..443dcf875 --- /dev/null +++ b/Profile/ProfileTests/DatesAndCalendarViewModelTests.swift @@ -0,0 +1,328 @@ +// +// DatesAndCalendarViewModelTests.swift +// Profile +// +// Created by Ivan Stepanok on 30.10.2024. +// + + +import SwiftyMocky +import XCTest +import EventKit +@testable import Profile +@testable import Core +import Theme +import SwiftUICore +import Combine + +final class DatesAndCalendarViewModelTests: XCTestCase { + + var cancellables: Set! + + override func setUp() { + super.setUp() + cancellables = [] + } + + func testLoadCalendarOptions() { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + let settings = CalendarSettings( + colorSelection: "accent", + calendarName: "Test Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + Given(profileStorage, .calendarSettings(getter: settings)) + Given(profileStorage, .lastCalendarName(getter: "Old Calendar")) + Given(profileStorage, .hideInactiveCourses(getter: true)) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + viewModel.loadCalendarOptions() + + // Then + XCTAssertEqual(viewModel.colorSelection?.colorString, "accent") + XCTAssertEqual(viewModel.accountSelection?.title, "iCloud") + XCTAssertEqual(viewModel.calendarName, "Test Calendar") + XCTAssertEqual(viewModel.oldCalendarName, "Old Calendar") + XCTAssertTrue(viewModel.courseCalendarSync) + XCTAssertTrue(viewModel.hideInactiveCourses) + } + + func testClearAllData() { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + viewModel.clearAllData() + + // Then + Verify(calendarManager, 1, .clearAllData(removeCalendar: .value(true))) + Verify(router, 1, .back(animated: .value(false))) + Verify(router, 1, .showDatesAndCalendar()) + XCTAssertTrue(viewModel.courseCalendarSync) + XCTAssertFalse(viewModel.showDisableCalendarSync) + XCTAssertFalse(viewModel.openNewCalendarView) + } + + func testSaveCalendarOptions() { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + var settings = CalendarSettings( + colorSelection: "accent", + calendarName: "Old Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + Given(profileStorage, .calendarSettings(getter: settings)) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + viewModel.calendarName = "New Calendar" + viewModel.colorSelection = .init(color: .red) + viewModel.accountSelection = .init(title: "Local") + viewModel.courseCalendarSync = false + viewModel.saveCalendarOptions() + + // Then + XCTAssertEqual(profileStorage.calendarSettings?.calendarName, "New Calendar") + XCTAssertEqual(profileStorage.calendarSettings?.colorSelection, "red") + XCTAssertEqual(profileStorage.calendarSettings?.accountSelection, "Local") + XCTAssertFalse(profileStorage.calendarSettings?.courseCalendarSync ?? true) + XCTAssertEqual(profileStorage.lastCalendarName, "New Calendar") + } + + func testFetchCoursesSuccess() async { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(calendarManager, .requestAccess(willReturn: true)) + + let courses = [ + CourseForSync( + id: UUID(), + courseID: "course-1", + name: "Course 1", + synced: true, + recentlyActive: true + ) + ] + Given(interactor, .enrollmentsStatus(willReturn: courses)) + Given(persistence, .getAllCourseStates(willReturn: [])) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + await viewModel.fetchCourses() + + // Then + XCTAssertEqual(viewModel.assignmentStatus, .synced) + XCTAssertEqual(viewModel.coursesForSync.count, 1) + XCTAssertEqual(viewModel.coursesForSync.first?.courseID, "course-1") + Verify(calendarManager, 1, .createCalendarIfNeeded()) + Verify(interactor, 1, .enrollmentsStatus()) + } + + func testRequestCalendarPermissionSuccess() async { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + Given(calendarManager, .requestAccess(willReturn: true)) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + await viewModel.requestCalendarPermission() + + // Then + XCTAssertTrue(viewModel.openNewCalendarView) + XCTAssertFalse(viewModel.showCalendaAccessDenied) + } + + func testRequestCalendarPermissionDenied() async { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + Given(calendarManager, .requestAccess(willReturn: false)) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + + // When + await viewModel.requestCalendarPermission() + + // Then + XCTAssertTrue(viewModel.showCalendaAccessDenied) + XCTAssertFalse(viewModel.openNewCalendarView) + } + + func testToggleSyncForCourse() { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + let course = CourseForSync( + id: UUID(), + courseID: "course-1", + name: "Course 1", + synced: false, + recentlyActive: true + ) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + viewModel.coursesForSync = [course] + + // When + viewModel.toggleSync(for: course) + + // Then + XCTAssertTrue(viewModel.coursesForSync.first?.synced ?? false) + XCTAssertEqual(viewModel.coursesForAdding.count, 1) + XCTAssertEqual(viewModel.coursesForAdding.first?.courseID, "course-1") + } + + func testDeleteOldCalendarIfNeeded() async { + // Given + let router = ProfileRouterMock() + let interactor = ProfileInteractorProtocolMock() + let persistence = ProfilePersistenceProtocolMock() + let calendarManager = CalendarManagerProtocolMock() + let connectivity = ConnectivityProtocolMock() + let profileStorage = ProfileStorageMock() + + let settings = CalendarSettings( + colorSelection: "accent", + calendarName: "Old Calendar", + accountSelection: "iCloud", + courseCalendarSync: true + ) + + let states = [ + CourseCalendarState(courseID: "123", checksum: "checksum"), + CourseCalendarState(courseID: "124", checksum: "checksum2") + ] + + Given(persistence, .getAllCourseStates(willReturn: states)) + Given(profileStorage, .calendarSettings(getter: settings)) + Given(connectivity, .isInternetAvaliable(getter: true)) + Given(calendarManager, .requestAccess(willReturn: true)) + + let courses = [ + CourseForSync( + id: UUID(), + courseID: "course-1", + name: "Course 1", + synced: true, + recentlyActive: true + ) + ] + Given(interactor, .enrollmentsStatus(willReturn: courses)) + + let viewModel = DatesAndCalendarViewModel( + router: router, + interactor: interactor, + profileStorage: profileStorage, + persistence: persistence, + calendarManager: calendarManager, + connectivity: connectivity + ) + viewModel.calendarName = "New Calendar" + + // When + await viewModel.deleteOldCalendarIfNeeded() + + // Then + Verify(calendarManager, 1, .removeOldCalendar()) + Verify(persistence, 1, .removeAllCourseCalendarEvents()) + } +} diff --git a/Profile/ProfileTests/ProfileMock.generated.swift b/Profile/ProfileTests/ProfileMock.generated.swift index f6d738dff..6a2424da6 100644 --- a/Profile/ProfileTests/ProfileMock.generated.swift +++ b/Profile/ProfileTests/ProfileMock.generated.swift @@ -978,9 +978,9 @@ open class BaseRouterMock: BaseRouter, Mock { } } -// MARK: - ConnectivityProtocol +// MARK: - CalendarManagerProtocol -open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { +open class CalendarManagerProtocolMock: CalendarManagerProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -1018,51 +1018,176 @@ open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { if scopes.contains(.perform) { methodPerformValues = [] } } - public var isInternetAvaliable: Bool { - get { invocations.append(.p_isInternetAvaliable_get); return __p_isInternetAvaliable ?? givenGetterValue(.p_isInternetAvaliable_get, "ConnectivityProtocolMock - stub value for isInternetAvaliable was not defined") } - } - private var __p_isInternetAvaliable: (Bool)? - public var isMobileData: Bool { - get { invocations.append(.p_isMobileData_get); return __p_isMobileData ?? givenGetterValue(.p_isMobileData_get, "ConnectivityProtocolMock - stub value for isMobileData was not defined") } - } - private var __p_isMobileData: (Bool)? - public var internetReachableSubject: CurrentValueSubject { - get { invocations.append(.p_internetReachableSubject_get); return __p_internetReachableSubject ?? givenGetterValue(.p_internetReachableSubject_get, "ConnectivityProtocolMock - stub value for internetReachableSubject was not defined") } - } - private var __p_internetReachableSubject: (CurrentValueSubject)? + open func createCalendarIfNeeded() { + addInvocation(.m_createCalendarIfNeeded) + let perform = methodPerformValue(.m_createCalendarIfNeeded) as? () -> Void + perform?() + } + + open func filterCoursesBySelected(fetchedCourses: [CourseForSync]) -> [CourseForSync] { + addInvocation(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) + let perform = methodPerformValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))) as? ([CourseForSync]) -> Void + perform?(`fetchedCourses`) + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>.value(`fetchedCourses`))).casted() + } catch { + onFatalFailure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + Failure("Stub return value not specified for filterCoursesBySelected(fetchedCourses: [CourseForSync]). Use given") + } + return __value + } + + open func removeOldCalendar() { + addInvocation(.m_removeOldCalendar) + let perform = methodPerformValue(.m_removeOldCalendar) as? () -> Void + perform?() + } + + open func removeOutdatedEvents(courseID: String) { + addInvocation(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeOutdatedEvents__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func syncCourse(courseID: String, courseName: String, dates: CourseDates) { + addInvocation(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) + let perform = methodPerformValue(.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter.value(`courseID`), Parameter.value(`courseName`), Parameter.value(`dates`))) as? (String, String, CourseDates) -> Void + perform?(`courseID`, `courseName`, `dates`) + } + + open func requestAccess() -> Bool { + addInvocation(.m_requestAccess) + let perform = methodPerformValue(.m_requestAccess) as? () -> Void + perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_requestAccess).casted() + } catch { + onFatalFailure("Stub return value not specified for requestAccess(). Use given") + Failure("Stub return value not specified for requestAccess(). Use given") + } + return __value + } + + open func courseStatus(courseID: String) -> SyncStatus { + addInvocation(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: SyncStatus + do { + __value = try methodReturnValue(.m_courseStatus__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch { + onFatalFailure("Stub return value not specified for courseStatus(courseID: String). Use given") + Failure("Stub return value not specified for courseStatus(courseID: String). Use given") + } + return __value + } + open func clearAllData(removeCalendar: Bool) { + addInvocation(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) + let perform = methodPerformValue(.m_clearAllData__removeCalendar_removeCalendar(Parameter.value(`removeCalendar`))) as? (Bool) -> Void + perform?(`removeCalendar`) + } + open func isDatesChanged(courseID: String, checksum: String) -> Bool { + addInvocation(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) + let perform = methodPerformValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))) as? (String, String) -> Void + perform?(`courseID`, `checksum`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter.value(`courseID`), Parameter.value(`checksum`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + Failure("Stub return value not specified for isDatesChanged(courseID: String, checksum: String). Use given") + } + return __value + } fileprivate enum MethodType { - case p_isInternetAvaliable_get - case p_isMobileData_get - case p_internetReachableSubject_get + case m_createCalendarIfNeeded + case m_filterCoursesBySelected__fetchedCourses_fetchedCourses(Parameter<[CourseForSync]>) + case m_removeOldCalendar + case m_removeOutdatedEvents__courseID_courseID(Parameter) + case m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(Parameter, Parameter, Parameter) + case m_requestAccess + case m_courseStatus__courseID_courseID(Parameter) + case m_clearAllData__removeCalendar_removeCalendar(Parameter) + case m_isDatesChanged__courseID_courseIDchecksum_checksum(Parameter, Parameter) static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { case (.p_isInternetAvaliable_get,.p_isInternetAvaliable_get): return Matcher.ComparisonResult.match - case (.p_isMobileData_get,.p_isMobileData_get): return Matcher.ComparisonResult.match - case (.p_internetReachableSubject_get,.p_internetReachableSubject_get): return Matcher.ComparisonResult.match + switch (lhs, rhs) { + case (.m_createCalendarIfNeeded, .m_createCalendarIfNeeded): return .match + + case (.m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let lhsFetchedcourses), .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(let rhsFetchedcourses)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsFetchedcourses, rhs: rhsFetchedcourses, with: matcher), lhsFetchedcourses, rhsFetchedcourses, "fetchedCourses")) + return Matcher.ComparisonResult(results) + + case (.m_removeOldCalendar, .m_removeOldCalendar): return .match + + case (.m_removeOutdatedEvents__courseID_courseID(let lhsCourseid), .m_removeOutdatedEvents__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let lhsCourseid, let lhsCoursename, let lhsDates), .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(let rhsCourseid, let rhsCoursename, let rhsDates)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCoursename, rhs: rhsCoursename, with: matcher), lhsCoursename, rhsCoursename, "courseName")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDates, rhs: rhsDates, with: matcher), lhsDates, rhsDates, "dates")) + return Matcher.ComparisonResult(results) + + case (.m_requestAccess, .m_requestAccess): return .match + + case (.m_courseStatus__courseID_courseID(let lhsCourseid), .m_courseStatus__courseID_courseID(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + return Matcher.ComparisonResult(results) + + case (.m_clearAllData__removeCalendar_removeCalendar(let lhsRemovecalendar), .m_clearAllData__removeCalendar_removeCalendar(let rhsRemovecalendar)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRemovecalendar, rhs: rhsRemovecalendar, with: matcher), lhsRemovecalendar, rhsRemovecalendar, "removeCalendar")) + return Matcher.ComparisonResult(results) + + case (.m_isDatesChanged__courseID_courseIDchecksum_checksum(let lhsCourseid, let lhsChecksum), .m_isDatesChanged__courseID_courseIDchecksum_checksum(let rhsCourseid, let rhsChecksum)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsChecksum, rhs: rhsChecksum, with: matcher), lhsChecksum, rhsChecksum, "checksum")) + return Matcher.ComparisonResult(results) default: return .none } } func intValue() -> Int { switch self { - case .p_isInternetAvaliable_get: return 0 - case .p_isMobileData_get: return 0 - case .p_internetReachableSubject_get: return 0 + case .m_createCalendarIfNeeded: return 0 + case let .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(p0): return p0.intValue + case .m_removeOldCalendar: return 0 + case let .m_removeOutdatedEvents__courseID_courseID(p0): return p0.intValue + case let .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_requestAccess: return 0 + case let .m_courseStatus__courseID_courseID(p0): return p0.intValue + case let .m_clearAllData__removeCalendar_removeCalendar(p0): return p0.intValue + case let .m_isDatesChanged__courseID_courseIDchecksum_checksum(p0, p1): return p0.intValue + p1.intValue } } func assertionName() -> String { switch self { - case .p_isInternetAvaliable_get: return "[get] .isInternetAvaliable" - case .p_isMobileData_get: return "[get] .isMobileData" - case .p_internetReachableSubject_get: return "[get] .internetReachableSubject" + case .m_createCalendarIfNeeded: return ".createCalendarIfNeeded()" + case .m_filterCoursesBySelected__fetchedCourses_fetchedCourses: return ".filterCoursesBySelected(fetchedCourses:)" + case .m_removeOldCalendar: return ".removeOldCalendar()" + case .m_removeOutdatedEvents__courseID_courseID: return ".removeOutdatedEvents(courseID:)" + case .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates: return ".syncCourse(courseID:courseName:dates:)" + case .m_requestAccess: return ".requestAccess()" + case .m_courseStatus__courseID_courseID: return ".courseStatus(courseID:)" + case .m_clearAllData__removeCalendar_removeCalendar: return ".clearAllData(removeCalendar:)" + case .m_isDatesChanged__courseID_courseIDchecksum_checksum: return ".isDatesChanged(courseID:checksum:)" } } } @@ -1075,30 +1200,94 @@ open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { super.init(products) } - public static func isInternetAvaliable(getter defaultValue: Bool...) -> PropertyStub { - return Given(method: .p_isInternetAvaliable_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) } - public static func isMobileData(getter defaultValue: Bool...) -> PropertyStub { - return Given(method: .p_isMobileData_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + public static func requestAccess(willReturn: Bool...) -> MethodStub { + return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) } - public static func internetReachableSubject(getter defaultValue: CurrentValueSubject...) -> PropertyStub { - return Given(method: .p_internetReachableSubject_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + public static func courseStatus(courseID: Parameter, willReturn: SyncStatus...) -> MethodStub { + return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, willProduce: (Stubber<[CourseForSync]>) -> Void) -> MethodStub { + let willReturn: [[CourseForSync]] = [] + let given: Given = { return Given(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func requestAccess(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_requestAccess, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func courseStatus(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [SyncStatus] = [] + let given: Given = { return Given(method: .m_courseStatus__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (SyncStatus).self) + willProduce(stubber) + return given + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given } - } public struct Verify { fileprivate var method: MethodType - public static var isInternetAvaliable: Verify { return Verify(method: .p_isInternetAvaliable_get) } - public static var isMobileData: Verify { return Verify(method: .p_isMobileData_get) } - public static var internetReachableSubject: Verify { return Verify(method: .p_internetReachableSubject_get) } + public static func createCalendarIfNeeded() -> Verify { return Verify(method: .m_createCalendarIfNeeded)} + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>) -> Verify { return Verify(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`))} + public static func removeOldCalendar() -> Verify { return Verify(method: .m_removeOldCalendar)} + public static func removeOutdatedEvents(courseID: Parameter) -> Verify { return Verify(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`))} + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter) -> Verify { return Verify(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`))} + public static func requestAccess() -> Verify { return Verify(method: .m_requestAccess)} + public static func courseStatus(courseID: Parameter) -> Verify { return Verify(method: .m_courseStatus__courseID_courseID(`courseID`))} + public static func clearAllData(removeCalendar: Parameter) -> Verify { return Verify(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`))} + public static func isDatesChanged(courseID: Parameter, checksum: Parameter) -> Verify { return Verify(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`))} } public struct Perform { fileprivate var method: MethodType var performs: Any + public static func createCalendarIfNeeded(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_createCalendarIfNeeded, performs: perform) + } + public static func filterCoursesBySelected(fetchedCourses: Parameter<[CourseForSync]>, perform: @escaping ([CourseForSync]) -> Void) -> Perform { + return Perform(method: .m_filterCoursesBySelected__fetchedCourses_fetchedCourses(`fetchedCourses`), performs: perform) + } + public static func removeOldCalendar(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeOldCalendar, performs: perform) + } + public static func removeOutdatedEvents(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeOutdatedEvents__courseID_courseID(`courseID`), performs: perform) + } + public static func syncCourse(courseID: Parameter, courseName: Parameter, dates: Parameter, perform: @escaping (String, String, CourseDates) -> Void) -> Perform { + return Perform(method: .m_syncCourse__courseID_courseIDcourseName_courseNamedates_dates(`courseID`, `courseName`, `dates`), performs: perform) + } + public static func requestAccess(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_requestAccess, performs: perform) + } + public static func courseStatus(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_courseStatus__courseID_courseID(`courseID`), performs: perform) + } + public static func clearAllData(removeCalendar: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_clearAllData__removeCalendar_removeCalendar(`removeCalendar`), performs: perform) + } + public static func isDatesChanged(courseID: Parameter, checksum: Parameter, perform: @escaping (String, String) -> Void) -> Perform { + return Perform(method: .m_isDatesChanged__courseID_courseIDchecksum_checksum(`courseID`, `checksum`), performs: perform) + } } public func given(_ method: Given) { @@ -1174,9 +1363,9 @@ open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { } } -// MARK: - CoreAnalytics +// MARK: - ConfigProtocol -open class CoreAnalyticsMock: CoreAnalytics, Mock { +open class ConfigProtocolMock: ConfigProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -1214,178 +1403,267 @@ open class CoreAnalyticsMock: CoreAnalytics, Mock { if scopes.contains(.perform) { methodPerformValues = [] } } + public var baseURL: URL { + get { invocations.append(.p_baseURL_get); return __p_baseURL ?? givenGetterValue(.p_baseURL_get, "ConfigProtocolMock - stub value for baseURL was not defined") } + } + private var __p_baseURL: (URL)? + public var baseSSOURL: URL { + get { invocations.append(.p_baseSSOURL_get); return __p_baseSSOURL ?? givenGetterValue(.p_baseSSOURL_get, "ConfigProtocolMock - stub value for baseSSOURL was not defined") } + } + private var __p_baseSSOURL: (URL)? + public var ssoFinishedURL: URL { + get { invocations.append(.p_ssoFinishedURL_get); return __p_ssoFinishedURL ?? givenGetterValue(.p_ssoFinishedURL_get, "ConfigProtocolMock - stub value for ssoFinishedURL was not defined") } + } + private var __p_ssoFinishedURL: (URL)? + public var ssoButtonTitle: [String: Any] { + get { invocations.append(.p_ssoButtonTitle_get); return __p_ssoButtonTitle ?? givenGetterValue(.p_ssoButtonTitle_get, "ConfigProtocolMock - stub value for ssoButtonTitle was not defined") } + } + private var __p_ssoButtonTitle: ([String: Any])? - open func trackEvent(_ event: AnalyticsEvent, parameters: [String: Any]?) { - addInvocation(.m_trackEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) - let perform = methodPerformValue(.m_trackEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, [String: Any]?) -> Void - perform?(`event`, `parameters`) - } + public var oAuthClientId: String { + get { invocations.append(.p_oAuthClientId_get); return __p_oAuthClientId ?? givenGetterValue(.p_oAuthClientId_get, "ConfigProtocolMock - stub value for oAuthClientId was not defined") } + } + private var __p_oAuthClientId: (String)? - open func trackEvent(_ event: AnalyticsEvent, biValue: EventBIValue, parameters: [String: Any]?) { - addInvocation(.m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) - let perform = methodPerformValue(.m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void - perform?(`event`, `biValue`, `parameters`) - } + public var tokenType: TokenType { + get { invocations.append(.p_tokenType_get); return __p_tokenType ?? givenGetterValue(.p_tokenType_get, "ConfigProtocolMock - stub value for tokenType was not defined") } + } + private var __p_tokenType: (TokenType)? - open func trackScreenEvent(_ event: AnalyticsEvent, parameters: [String: Any]?) { - addInvocation(.m_trackScreenEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) - let perform = methodPerformValue(.m_trackScreenEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, [String: Any]?) -> Void - perform?(`event`, `parameters`) - } + public var feedbackEmail: String { + get { invocations.append(.p_feedbackEmail_get); return __p_feedbackEmail ?? givenGetterValue(.p_feedbackEmail_get, "ConfigProtocolMock - stub value for feedbackEmail was not defined") } + } + private var __p_feedbackEmail: (String)? - open func trackScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue, parameters: [String: Any]?) { - addInvocation(.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) - let perform = methodPerformValue(.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void - perform?(`event`, `biValue`, `parameters`) - } + public var appStoreLink: String { + get { invocations.append(.p_appStoreLink_get); return __p_appStoreLink ?? givenGetterValue(.p_appStoreLink_get, "ConfigProtocolMock - stub value for appStoreLink was not defined") } + } + private var __p_appStoreLink: (String)? - open func appreview(_ event: AnalyticsEvent, biValue: EventBIValue, action: String?, rating: Int?) { - addInvocation(.m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter.value(`event`), Parameter.value(`biValue`), Parameter.value(`action`), Parameter.value(`rating`))) - let perform = methodPerformValue(.m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter.value(`event`), Parameter.value(`biValue`), Parameter.value(`action`), Parameter.value(`rating`))) as? (AnalyticsEvent, EventBIValue, String?, Int?) -> Void - perform?(`event`, `biValue`, `action`, `rating`) - } + public var faq: URL? { + get { invocations.append(.p_faq_get); return __p_faq ?? optionalGivenGetterValue(.p_faq_get, "ConfigProtocolMock - stub value for faq was not defined") } + } + private var __p_faq: (URL)? - open func videoQualityChanged(_ event: AnalyticsEvent, bivalue: EventBIValue, value: String, oldValue: String) { - addInvocation(.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter.value(`event`), Parameter.value(`bivalue`), Parameter.value(`value`), Parameter.value(`oldValue`))) - let perform = methodPerformValue(.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter.value(`event`), Parameter.value(`bivalue`), Parameter.value(`value`), Parameter.value(`oldValue`))) as? (AnalyticsEvent, EventBIValue, String, String) -> Void - perform?(`event`, `bivalue`, `value`, `oldValue`) - } + public var platformName: String { + get { invocations.append(.p_platformName_get); return __p_platformName ?? givenGetterValue(.p_platformName_get, "ConfigProtocolMock - stub value for platformName was not defined") } + } + private var __p_platformName: (String)? - open func trackEvent(_ event: AnalyticsEvent) { - addInvocation(.m_trackEvent__event(Parameter.value(`event`))) - let perform = methodPerformValue(.m_trackEvent__event(Parameter.value(`event`))) as? (AnalyticsEvent) -> Void - perform?(`event`) - } + public var agreement: AgreementConfig { + get { invocations.append(.p_agreement_get); return __p_agreement ?? givenGetterValue(.p_agreement_get, "ConfigProtocolMock - stub value for agreement was not defined") } + } + private var __p_agreement: (AgreementConfig)? - open func trackEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { - addInvocation(.m_trackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) - let perform = methodPerformValue(.m_trackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void - perform?(`event`, `biValue`) - } + public var firebase: FirebaseConfig { + get { invocations.append(.p_firebase_get); return __p_firebase ?? givenGetterValue(.p_firebase_get, "ConfigProtocolMock - stub value for firebase was not defined") } + } + private var __p_firebase: (FirebaseConfig)? - open func trackScreenEvent(_ event: AnalyticsEvent) { - addInvocation(.m_trackScreenEvent__event(Parameter.value(`event`))) - let perform = methodPerformValue(.m_trackScreenEvent__event(Parameter.value(`event`))) as? (AnalyticsEvent) -> Void - perform?(`event`) - } + public var facebook: FacebookConfig { + get { invocations.append(.p_facebook_get); return __p_facebook ?? givenGetterValue(.p_facebook_get, "ConfigProtocolMock - stub value for facebook was not defined") } + } + private var __p_facebook: (FacebookConfig)? - open func trackScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { - addInvocation(.m_trackScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) - let perform = methodPerformValue(.m_trackScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void - perform?(`event`, `biValue`) - } + public var microsoft: MicrosoftConfig { + get { invocations.append(.p_microsoft_get); return __p_microsoft ?? givenGetterValue(.p_microsoft_get, "ConfigProtocolMock - stub value for microsoft was not defined") } + } + private var __p_microsoft: (MicrosoftConfig)? + public var google: GoogleConfig { + get { invocations.append(.p_google_get); return __p_google ?? givenGetterValue(.p_google_get, "ConfigProtocolMock - stub value for google was not defined") } + } + private var __p_google: (GoogleConfig)? - fileprivate enum MethodType { - case m_trackEvent__eventparameters_parameters(Parameter, Parameter<[String: Any]?>) - case m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter, Parameter, Parameter<[String: Any]?>) - case m_trackScreenEvent__eventparameters_parameters(Parameter, Parameter<[String: Any]?>) - case m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter, Parameter, Parameter<[String: Any]?>) - case m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter, Parameter, Parameter, Parameter) - case m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter, Parameter, Parameter, Parameter) - case m_trackEvent__event(Parameter) - case m_trackEvent__eventbiValue_biValue(Parameter, Parameter) - case m_trackScreenEvent__event(Parameter) - case m_trackScreenEvent__eventbiValue_biValue(Parameter, Parameter) + public var appleSignIn: AppleSignInConfig { + get { invocations.append(.p_appleSignIn_get); return __p_appleSignIn ?? givenGetterValue(.p_appleSignIn_get, "ConfigProtocolMock - stub value for appleSignIn was not defined") } + } + private var __p_appleSignIn: (AppleSignInConfig)? - static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { - case (.m_trackEvent__eventparameters_parameters(let lhsEvent, let lhsParameters), .m_trackEvent__eventparameters_parameters(let rhsEvent, let rhsParameters)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) - return Matcher.ComparisonResult(results) + public var features: FeaturesConfig { + get { invocations.append(.p_features_get); return __p_features ?? givenGetterValue(.p_features_get, "ConfigProtocolMock - stub value for features was not defined") } + } + private var __p_features: (FeaturesConfig)? - case (.m_trackEvent__eventbiValue_biValueparameters_parameters(let lhsEvent, let lhsBivalue, let lhsParameters), .m_trackEvent__eventbiValue_biValueparameters_parameters(let rhsEvent, let rhsBivalue, let rhsParameters)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) - return Matcher.ComparisonResult(results) + public var theme: ThemeConfig { + get { invocations.append(.p_theme_get); return __p_theme ?? givenGetterValue(.p_theme_get, "ConfigProtocolMock - stub value for theme was not defined") } + } + private var __p_theme: (ThemeConfig)? - case (.m_trackScreenEvent__eventparameters_parameters(let lhsEvent, let lhsParameters), .m_trackScreenEvent__eventparameters_parameters(let rhsEvent, let rhsParameters)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) - return Matcher.ComparisonResult(results) + public var uiComponents: UIComponentsConfig { + get { invocations.append(.p_uiComponents_get); return __p_uiComponents ?? givenGetterValue(.p_uiComponents_get, "ConfigProtocolMock - stub value for uiComponents was not defined") } + } + private var __p_uiComponents: (UIComponentsConfig)? - case (.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(let lhsEvent, let lhsBivalue, let lhsParameters), .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(let rhsEvent, let rhsBivalue, let rhsParameters)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) - return Matcher.ComparisonResult(results) + public var discovery: DiscoveryConfig { + get { invocations.append(.p_discovery_get); return __p_discovery ?? givenGetterValue(.p_discovery_get, "ConfigProtocolMock - stub value for discovery was not defined") } + } + private var __p_discovery: (DiscoveryConfig)? - case (.m_appreview__eventbiValue_biValueaction_actionrating_rating(let lhsEvent, let lhsBivalue, let lhsAction, let lhsRating), .m_appreview__eventbiValue_biValueaction_actionrating_rating(let rhsEvent, let rhsBivalue, let rhsAction, let rhsRating)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRating, rhs: rhsRating, with: matcher), lhsRating, rhsRating, "rating")) - return Matcher.ComparisonResult(results) + public var dashboard: DashboardConfig { + get { invocations.append(.p_dashboard_get); return __p_dashboard ?? givenGetterValue(.p_dashboard_get, "ConfigProtocolMock - stub value for dashboard was not defined") } + } + private var __p_dashboard: (DashboardConfig)? - case (.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(let lhsEvent, let lhsBivalue, let lhsValue, let lhsOldvalue), .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(let rhsEvent, let rhsBivalue, let rhsValue, let rhsOldvalue)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "bivalue")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsValue, rhs: rhsValue, with: matcher), lhsValue, rhsValue, "value")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsOldvalue, rhs: rhsOldvalue, with: matcher), lhsOldvalue, rhsOldvalue, "oldValue")) - return Matcher.ComparisonResult(results) + public var braze: BrazeConfig { + get { invocations.append(.p_braze_get); return __p_braze ?? givenGetterValue(.p_braze_get, "ConfigProtocolMock - stub value for braze was not defined") } + } + private var __p_braze: (BrazeConfig)? - case (.m_trackEvent__event(let lhsEvent), .m_trackEvent__event(let rhsEvent)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - return Matcher.ComparisonResult(results) + public var branch: BranchConfig { + get { invocations.append(.p_branch_get); return __p_branch ?? givenGetterValue(.p_branch_get, "ConfigProtocolMock - stub value for branch was not defined") } + } + private var __p_branch: (BranchConfig)? - case (.m_trackEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_trackEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - return Matcher.ComparisonResult(results) + public var segment: SegmentConfig { + get { invocations.append(.p_segment_get); return __p_segment ?? givenGetterValue(.p_segment_get, "ConfigProtocolMock - stub value for segment was not defined") } + } + private var __p_segment: (SegmentConfig)? - case (.m_trackScreenEvent__event(let lhsEvent), .m_trackScreenEvent__event(let rhsEvent)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - return Matcher.ComparisonResult(results) + public var program: DiscoveryConfig { + get { invocations.append(.p_program_get); return __p_program ?? givenGetterValue(.p_program_get, "ConfigProtocolMock - stub value for program was not defined") } + } + private var __p_program: (DiscoveryConfig)? - case (.m_trackScreenEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_trackScreenEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - return Matcher.ComparisonResult(results) + public var URIScheme: String { + get { invocations.append(.p_URIScheme_get); return __p_URIScheme ?? givenGetterValue(.p_URIScheme_get, "ConfigProtocolMock - stub value for URIScheme was not defined") } + } + private var __p_URIScheme: (String)? + + public var fullStory: FullStoryConfig { + get { invocations.append(.p_fullStory_get); return __p_fullStory ?? givenGetterValue(.p_fullStory_get, "ConfigProtocolMock - stub value for fullStory was not defined") } + } + private var __p_fullStory: (FullStoryConfig)? + + + + + + + fileprivate enum MethodType { + case p_baseURL_get + case p_baseSSOURL_get + case p_ssoFinishedURL_get + case p_ssoButtonTitle_get + case p_oAuthClientId_get + case p_tokenType_get + case p_feedbackEmail_get + case p_appStoreLink_get + case p_faq_get + case p_platformName_get + case p_agreement_get + case p_firebase_get + case p_facebook_get + case p_microsoft_get + case p_google_get + case p_appleSignIn_get + case p_features_get + case p_theme_get + case p_uiComponents_get + case p_discovery_get + case p_dashboard_get + case p_braze_get + case p_branch_get + case p_segment_get + case p_program_get + case p_URIScheme_get + case p_fullStory_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_baseURL_get,.p_baseURL_get): return Matcher.ComparisonResult.match + case (.p_baseSSOURL_get,.p_baseSSOURL_get): return Matcher.ComparisonResult.match + case (.p_ssoFinishedURL_get,.p_ssoFinishedURL_get): return Matcher.ComparisonResult.match + case (.p_ssoButtonTitle_get,.p_ssoButtonTitle_get): return Matcher.ComparisonResult.match + case (.p_oAuthClientId_get,.p_oAuthClientId_get): return Matcher.ComparisonResult.match + case (.p_tokenType_get,.p_tokenType_get): return Matcher.ComparisonResult.match + case (.p_feedbackEmail_get,.p_feedbackEmail_get): return Matcher.ComparisonResult.match + case (.p_appStoreLink_get,.p_appStoreLink_get): return Matcher.ComparisonResult.match + case (.p_faq_get,.p_faq_get): return Matcher.ComparisonResult.match + case (.p_platformName_get,.p_platformName_get): return Matcher.ComparisonResult.match + case (.p_agreement_get,.p_agreement_get): return Matcher.ComparisonResult.match + case (.p_firebase_get,.p_firebase_get): return Matcher.ComparisonResult.match + case (.p_facebook_get,.p_facebook_get): return Matcher.ComparisonResult.match + case (.p_microsoft_get,.p_microsoft_get): return Matcher.ComparisonResult.match + case (.p_google_get,.p_google_get): return Matcher.ComparisonResult.match + case (.p_appleSignIn_get,.p_appleSignIn_get): return Matcher.ComparisonResult.match + case (.p_features_get,.p_features_get): return Matcher.ComparisonResult.match + case (.p_theme_get,.p_theme_get): return Matcher.ComparisonResult.match + case (.p_uiComponents_get,.p_uiComponents_get): return Matcher.ComparisonResult.match + case (.p_discovery_get,.p_discovery_get): return Matcher.ComparisonResult.match + case (.p_dashboard_get,.p_dashboard_get): return Matcher.ComparisonResult.match + case (.p_braze_get,.p_braze_get): return Matcher.ComparisonResult.match + case (.p_branch_get,.p_branch_get): return Matcher.ComparisonResult.match + case (.p_segment_get,.p_segment_get): return Matcher.ComparisonResult.match + case (.p_program_get,.p_program_get): return Matcher.ComparisonResult.match + case (.p_URIScheme_get,.p_URIScheme_get): return Matcher.ComparisonResult.match + case (.p_fullStory_get,.p_fullStory_get): return Matcher.ComparisonResult.match default: return .none } } func intValue() -> Int { switch self { - case let .m_trackEvent__eventparameters_parameters(p0, p1): return p0.intValue + p1.intValue - case let .m_trackEvent__eventbiValue_biValueparameters_parameters(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue - case let .m_trackScreenEvent__eventparameters_parameters(p0, p1): return p0.intValue + p1.intValue - case let .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue - case let .m_appreview__eventbiValue_biValueaction_actionrating_rating(p0, p1, p2, p3): return p0.intValue + p1.intValue + p2.intValue + p3.intValue - case let .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(p0, p1, p2, p3): return p0.intValue + p1.intValue + p2.intValue + p3.intValue - case let .m_trackEvent__event(p0): return p0.intValue - case let .m_trackEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue - case let .m_trackScreenEvent__event(p0): return p0.intValue - case let .m_trackScreenEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue + case .p_baseURL_get: return 0 + case .p_baseSSOURL_get: return 0 + case .p_ssoFinishedURL_get: return 0 + case .p_ssoButtonTitle_get: return 0 + case .p_oAuthClientId_get: return 0 + case .p_tokenType_get: return 0 + case .p_feedbackEmail_get: return 0 + case .p_appStoreLink_get: return 0 + case .p_faq_get: return 0 + case .p_platformName_get: return 0 + case .p_agreement_get: return 0 + case .p_firebase_get: return 0 + case .p_facebook_get: return 0 + case .p_microsoft_get: return 0 + case .p_google_get: return 0 + case .p_appleSignIn_get: return 0 + case .p_features_get: return 0 + case .p_theme_get: return 0 + case .p_uiComponents_get: return 0 + case .p_discovery_get: return 0 + case .p_dashboard_get: return 0 + case .p_braze_get: return 0 + case .p_branch_get: return 0 + case .p_segment_get: return 0 + case .p_program_get: return 0 + case .p_URIScheme_get: return 0 + case .p_fullStory_get: return 0 } } func assertionName() -> String { switch self { - case .m_trackEvent__eventparameters_parameters: return ".trackEvent(_:parameters:)" - case .m_trackEvent__eventbiValue_biValueparameters_parameters: return ".trackEvent(_:biValue:parameters:)" - case .m_trackScreenEvent__eventparameters_parameters: return ".trackScreenEvent(_:parameters:)" - case .m_trackScreenEvent__eventbiValue_biValueparameters_parameters: return ".trackScreenEvent(_:biValue:parameters:)" - case .m_appreview__eventbiValue_biValueaction_actionrating_rating: return ".appreview(_:biValue:action:rating:)" - case .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue: return ".videoQualityChanged(_:bivalue:value:oldValue:)" - case .m_trackEvent__event: return ".trackEvent(_:)" - case .m_trackEvent__eventbiValue_biValue: return ".trackEvent(_:biValue:)" - case .m_trackScreenEvent__event: return ".trackScreenEvent(_:)" - case .m_trackScreenEvent__eventbiValue_biValue: return ".trackScreenEvent(_:biValue:)" + case .p_baseURL_get: return "[get] .baseURL" + case .p_baseSSOURL_get: return "[get] .baseSSOURL" + case .p_ssoFinishedURL_get: return "[get] .ssoFinishedURL" + case .p_ssoButtonTitle_get: return "[get] .ssoButtonTitle" + case .p_oAuthClientId_get: return "[get] .oAuthClientId" + case .p_tokenType_get: return "[get] .tokenType" + case .p_feedbackEmail_get: return "[get] .feedbackEmail" + case .p_appStoreLink_get: return "[get] .appStoreLink" + case .p_faq_get: return "[get] .faq" + case .p_platformName_get: return "[get] .platformName" + case .p_agreement_get: return "[get] .agreement" + case .p_firebase_get: return "[get] .firebase" + case .p_facebook_get: return "[get] .facebook" + case .p_microsoft_get: return "[get] .microsoft" + case .p_google_get: return "[get] .google" + case .p_appleSignIn_get: return "[get] .appleSignIn" + case .p_features_get: return "[get] .features" + case .p_theme_get: return "[get] .theme" + case .p_uiComponents_get: return "[get] .uiComponents" + case .p_discovery_get: return "[get] .discovery" + case .p_dashboard_get: return "[get] .dashboard" + case .p_braze_get: return "[get] .braze" + case .p_branch_get: return "[get] .branch" + case .p_segment_get: return "[get] .segment" + case .p_program_get: return "[get] .program" + case .p_URIScheme_get: return "[get] .URIScheme" + case .p_fullStory_get: return "[get] .fullStory" } } } @@ -1398,58 +1676,126 @@ open class CoreAnalyticsMock: CoreAnalytics, Mock { super.init(products) } + public static func baseURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func baseSSOURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_baseSSOURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoFinishedURL(getter defaultValue: URL...) -> PropertyStub { + return Given(method: .p_ssoFinishedURL_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func ssoButtonTitle(getter defaultValue: [String: Any]...) -> PropertyStub { + return Given(method: .p_ssoButtonTitle_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func oAuthClientId(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_oAuthClientId_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func tokenType(getter defaultValue: TokenType...) -> PropertyStub { + return Given(method: .p_tokenType_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func feedbackEmail(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_feedbackEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appStoreLink(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_appStoreLink_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func faq(getter defaultValue: URL?...) -> PropertyStub { + return Given(method: .p_faq_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func platformName(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_platformName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func agreement(getter defaultValue: AgreementConfig...) -> PropertyStub { + return Given(method: .p_agreement_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firebase(getter defaultValue: FirebaseConfig...) -> PropertyStub { + return Given(method: .p_firebase_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func facebook(getter defaultValue: FacebookConfig...) -> PropertyStub { + return Given(method: .p_facebook_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func microsoft(getter defaultValue: MicrosoftConfig...) -> PropertyStub { + return Given(method: .p_microsoft_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func google(getter defaultValue: GoogleConfig...) -> PropertyStub { + return Given(method: .p_google_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignIn(getter defaultValue: AppleSignInConfig...) -> PropertyStub { + return Given(method: .p_appleSignIn_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func features(getter defaultValue: FeaturesConfig...) -> PropertyStub { + return Given(method: .p_features_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func theme(getter defaultValue: ThemeConfig...) -> PropertyStub { + return Given(method: .p_theme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func uiComponents(getter defaultValue: UIComponentsConfig...) -> PropertyStub { + return Given(method: .p_uiComponents_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func discovery(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_discovery_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func dashboard(getter defaultValue: DashboardConfig...) -> PropertyStub { + return Given(method: .p_dashboard_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func braze(getter defaultValue: BrazeConfig...) -> PropertyStub { + return Given(method: .p_braze_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func branch(getter defaultValue: BranchConfig...) -> PropertyStub { + return Given(method: .p_branch_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func segment(getter defaultValue: SegmentConfig...) -> PropertyStub { + return Given(method: .p_segment_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func program(getter defaultValue: DiscoveryConfig...) -> PropertyStub { + return Given(method: .p_program_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func URIScheme(getter defaultValue: String...) -> PropertyStub { + return Given(method: .p_URIScheme_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func fullStory(getter defaultValue: FullStoryConfig...) -> PropertyStub { + return Given(method: .p_fullStory_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } } public struct Verify { fileprivate var method: MethodType - public static func trackEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackEvent__eventparameters_parameters(`event`, `parameters`))} - public static func trackEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`))} - public static func trackScreenEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackScreenEvent__eventparameters_parameters(`event`, `parameters`))} - public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`))} - public static func appreview(_ event: Parameter, biValue: Parameter, action: Parameter, rating: Parameter) -> Verify { return Verify(method: .m_appreview__eventbiValue_biValueaction_actionrating_rating(`event`, `biValue`, `action`, `rating`))} - public static func videoQualityChanged(_ event: Parameter, bivalue: Parameter, value: Parameter, oldValue: Parameter) -> Verify { return Verify(method: .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(`event`, `bivalue`, `value`, `oldValue`))} - public static func trackEvent(_ event: Parameter) -> Verify { return Verify(method: .m_trackEvent__event(`event`))} - public static func trackEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_trackEvent__eventbiValue_biValue(`event`, `biValue`))} - public static func trackScreenEvent(_ event: Parameter) -> Verify { return Verify(method: .m_trackScreenEvent__event(`event`))} - public static func trackScreenEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_trackScreenEvent__eventbiValue_biValue(`event`, `biValue`))} + public static var baseURL: Verify { return Verify(method: .p_baseURL_get) } + public static var baseSSOURL: Verify { return Verify(method: .p_baseSSOURL_get) } + public static var ssoFinishedURL: Verify { return Verify(method: .p_ssoFinishedURL_get) } + public static var ssoButtonTitle: Verify { return Verify(method: .p_ssoButtonTitle_get) } + public static var oAuthClientId: Verify { return Verify(method: .p_oAuthClientId_get) } + public static var tokenType: Verify { return Verify(method: .p_tokenType_get) } + public static var feedbackEmail: Verify { return Verify(method: .p_feedbackEmail_get) } + public static var appStoreLink: Verify { return Verify(method: .p_appStoreLink_get) } + public static var faq: Verify { return Verify(method: .p_faq_get) } + public static var platformName: Verify { return Verify(method: .p_platformName_get) } + public static var agreement: Verify { return Verify(method: .p_agreement_get) } + public static var firebase: Verify { return Verify(method: .p_firebase_get) } + public static var facebook: Verify { return Verify(method: .p_facebook_get) } + public static var microsoft: Verify { return Verify(method: .p_microsoft_get) } + public static var google: Verify { return Verify(method: .p_google_get) } + public static var appleSignIn: Verify { return Verify(method: .p_appleSignIn_get) } + public static var features: Verify { return Verify(method: .p_features_get) } + public static var theme: Verify { return Verify(method: .p_theme_get) } + public static var uiComponents: Verify { return Verify(method: .p_uiComponents_get) } + public static var discovery: Verify { return Verify(method: .p_discovery_get) } + public static var dashboard: Verify { return Verify(method: .p_dashboard_get) } + public static var braze: Verify { return Verify(method: .p_braze_get) } + public static var branch: Verify { return Verify(method: .p_branch_get) } + public static var segment: Verify { return Verify(method: .p_segment_get) } + public static var program: Verify { return Verify(method: .p_program_get) } + public static var URIScheme: Verify { return Verify(method: .p_URIScheme_get) } + public static var fullStory: Verify { return Verify(method: .p_fullStory_get) } } public struct Perform { fileprivate var method: MethodType var performs: Any - public static func trackEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, [String: Any]?) -> Void) -> Perform { - return Perform(method: .m_trackEvent__eventparameters_parameters(`event`, `parameters`), performs: perform) - } - public static func trackEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void) -> Perform { - return Perform(method: .m_trackEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`), performs: perform) - } - public static func trackScreenEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, [String: Any]?) -> Void) -> Perform { - return Perform(method: .m_trackScreenEvent__eventparameters_parameters(`event`, `parameters`), performs: perform) - } - public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void) -> Perform { - return Perform(method: .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`), performs: perform) - } - public static func appreview(_ event: Parameter, biValue: Parameter, action: Parameter, rating: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue, String?, Int?) -> Void) -> Perform { - return Perform(method: .m_appreview__eventbiValue_biValueaction_actionrating_rating(`event`, `biValue`, `action`, `rating`), performs: perform) - } - public static func videoQualityChanged(_ event: Parameter, bivalue: Parameter, value: Parameter, oldValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue, String, String) -> Void) -> Perform { - return Perform(method: .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(`event`, `bivalue`, `value`, `oldValue`), performs: perform) - } - public static func trackEvent(_ event: Parameter, perform: @escaping (AnalyticsEvent) -> Void) -> Perform { - return Perform(method: .m_trackEvent__event(`event`), performs: perform) - } - public static func trackEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { - return Perform(method: .m_trackEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) - } - public static func trackScreenEvent(_ event: Parameter, perform: @escaping (AnalyticsEvent) -> Void) -> Perform { - return Perform(method: .m_trackScreenEvent__event(`event`), performs: perform) - } - public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { - return Perform(method: .m_trackScreenEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) - } } public func given(_ method: Given) { @@ -1525,9 +1871,9 @@ open class CoreAnalyticsMock: CoreAnalytics, Mock { } } -// MARK: - CorePersistenceProtocol +// MARK: - ConnectivityProtocol -open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { +open class ConnectivityProtocolMock: ConnectivityProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -1565,269 +1911,343 @@ open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { if scopes.contains(.perform) { methodPerformValues = [] } } + public var isInternetAvaliable: Bool { + get { invocations.append(.p_isInternetAvaliable_get); return __p_isInternetAvaliable ?? givenGetterValue(.p_isInternetAvaliable_get, "ConnectivityProtocolMock - stub value for isInternetAvaliable was not defined") } + } + private var __p_isInternetAvaliable: (Bool)? + + public var isMobileData: Bool { + get { invocations.append(.p_isMobileData_get); return __p_isMobileData ?? givenGetterValue(.p_isMobileData_get, "ConnectivityProtocolMock - stub value for isMobileData was not defined") } + } + private var __p_isMobileData: (Bool)? + + public var internetReachableSubject: CurrentValueSubject { + get { invocations.append(.p_internetReachableSubject_get); return __p_internetReachableSubject ?? givenGetterValue(.p_internetReachableSubject_get, "ConnectivityProtocolMock - stub value for internetReachableSubject was not defined") } + } + private var __p_internetReachableSubject: (CurrentValueSubject)? - open func set(userId: Int) { - addInvocation(.m_set__userId_userId(Parameter.value(`userId`))) - let perform = methodPerformValue(.m_set__userId_userId(Parameter.value(`userId`))) as? (Int) -> Void - perform?(`userId`) - } - open func getUserID() -> Int? { - addInvocation(.m_getUserID) - let perform = methodPerformValue(.m_getUserID) as? () -> Void - perform?() - var __value: Int? = nil - do { - __value = try methodReturnValue(.m_getUserID).casted() - } catch { - // do nothing - } - return __value - } - open func publisher() -> AnyPublisher { - addInvocation(.m_publisher) - let perform = methodPerformValue(.m_publisher) as? () -> Void - perform?() - var __value: AnyPublisher - do { - __value = try methodReturnValue(.m_publisher).casted() - } catch { - onFatalFailure("Stub return value not specified for publisher(). Use given") - Failure("Stub return value not specified for publisher(). Use given") - } - return __value + fileprivate enum MethodType { + case p_isInternetAvaliable_get + case p_isMobileData_get + case p_internetReachableSubject_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_isInternetAvaliable_get,.p_isInternetAvaliable_get): return Matcher.ComparisonResult.match + case (.p_isMobileData_get,.p_isMobileData_get): return Matcher.ComparisonResult.match + case (.p_internetReachableSubject_get,.p_internetReachableSubject_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_isInternetAvaliable_get: return 0 + case .p_isMobileData_get: return 0 + case .p_internetReachableSubject_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .p_isInternetAvaliable_get: return "[get] .isInternetAvaliable" + case .p_isMobileData_get: return "[get] .isMobileData" + case .p_internetReachableSubject_get: return "[get] .internetReachableSubject" + } + } } - open func addToDownloadQueue(tasks: [DownloadDataTask]) { - addInvocation(.m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>.value(`tasks`))) - let perform = methodPerformValue(.m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>.value(`tasks`))) as? ([DownloadDataTask]) -> Void - perform?(`tasks`) + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func isInternetAvaliable(getter defaultValue: Bool...) -> PropertyStub { + return Given(method: .p_isInternetAvaliable_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func isMobileData(getter defaultValue: Bool...) -> PropertyStub { + return Given(method: .p_isMobileData_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func internetReachableSubject(getter defaultValue: CurrentValueSubject...) -> PropertyStub { + return Given(method: .p_internetReachableSubject_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + } - open func saveOfflineProgress(progress: OfflineProgress) { - addInvocation(.m_saveOfflineProgress__progress_progress(Parameter.value(`progress`))) - let perform = methodPerformValue(.m_saveOfflineProgress__progress_progress(Parameter.value(`progress`))) as? (OfflineProgress) -> Void - perform?(`progress`) + public struct Verify { + fileprivate var method: MethodType + + public static var isInternetAvaliable: Verify { return Verify(method: .p_isInternetAvaliable_get) } + public static var isMobileData: Verify { return Verify(method: .p_isMobileData_get) } + public static var internetReachableSubject: Verify { return Verify(method: .p_internetReachableSubject_get) } } - open func loadProgress(for blockID: String) -> OfflineProgress? { - addInvocation(.m_loadProgress__for_blockID(Parameter.value(`blockID`))) - let perform = methodPerformValue(.m_loadProgress__for_blockID(Parameter.value(`blockID`))) as? (String) -> Void - perform?(`blockID`) - var __value: OfflineProgress? = nil - do { - __value = try methodReturnValue(.m_loadProgress__for_blockID(Parameter.value(`blockID`))).casted() - } catch { - // do nothing - } - return __value + public struct Perform { + fileprivate var method: MethodType + var performs: Any + } - open func loadAllOfflineProgress() -> [OfflineProgress] { - addInvocation(.m_loadAllOfflineProgress) - let perform = methodPerformValue(.m_loadAllOfflineProgress) as? () -> Void - perform?() - var __value: [OfflineProgress] - do { - __value = try methodReturnValue(.m_loadAllOfflineProgress).casted() - } catch { - onFatalFailure("Stub return value not specified for loadAllOfflineProgress(). Use given") - Failure("Stub return value not specified for loadAllOfflineProgress(). Use given") - } - return __value + public func given(_ method: Given) { + methodReturnValues.append(method) } - open func deleteProgress(for blockID: String) { - addInvocation(.m_deleteProgress__for_blockID(Parameter.value(`blockID`))) - let perform = methodPerformValue(.m_deleteProgress__for_blockID(Parameter.value(`blockID`))) as? (String) -> Void - perform?(`blockID`) + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } } - open func deleteAllProgress() { - addInvocation(.m_deleteAllProgress) - let perform = methodPerformValue(.m_deleteAllProgress) as? () -> Void - perform?() + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) } - open func addToDownloadQueue(blocks: [CourseBlock], downloadQuality: DownloadQuality) { - addInvocation(.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>.value(`blocks`), Parameter.value(`downloadQuality`))) - let perform = methodPerformValue(.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>.value(`blocks`), Parameter.value(`downloadQuality`))) as? ([CourseBlock], DownloadQuality) -> Void - perform?(`blocks`, `downloadQuality`) + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } } - - open func nextBlockForDownloading() -> DownloadDataTask? { - addInvocation(.m_nextBlockForDownloading) - let perform = methodPerformValue(.m_nextBlockForDownloading) as? () -> Void - perform?() - var __value: DownloadDataTask? = nil - do { - __value = try methodReturnValue(.m_nextBlockForDownloading).casted() - } catch { - // do nothing - } - return __value + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product } - - open func updateDownloadState(id: String, state: DownloadState, resumeData: Data?) { - addInvocation(.m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter.value(`id`), Parameter.value(`state`), Parameter.value(`resumeData`))) - let perform = methodPerformValue(.m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter.value(`id`), Parameter.value(`state`), Parameter.value(`resumeData`))) as? (String, DownloadState, Data?) -> Void - perform?(`id`, `state`, `resumeData`) + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs } - - open func deleteDownloadDataTask(id: String) throws { - addInvocation(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))) - let perform = methodPerformValue(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))) as? (String) -> Void - perform?(`id`) - do { - _ = try methodReturnValue(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } } - - open func saveDownloadDataTask(_ task: DownloadDataTask) { - addInvocation(.m_saveDownloadDataTask__task(Parameter.value(`task`))) - let perform = methodPerformValue(.m_saveDownloadDataTask__task(Parameter.value(`task`))) as? (DownloadDataTask) -> Void - perform?(`task`) + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count } - - open func downloadDataTask(for blockId: String) -> DownloadDataTask? { - addInvocation(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))) - let perform = methodPerformValue(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))) as? (String) -> Void - perform?(`blockId`) - var __value: DownloadDataTask? = nil - do { - __value = try methodReturnValue(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))).casted() - } catch { - // do nothing - } - return __value + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } } - - open func getDownloadDataTasks() -> [DownloadDataTask] { - addInvocation(.m_getDownloadDataTasks) - let perform = methodPerformValue(.m_getDownloadDataTasks) as? () -> Void - perform?() - var __value: [DownloadDataTask] - do { - __value = try methodReturnValue(.m_getDownloadDataTasks).casted() - } catch { - onFatalFailure("Stub return value not specified for getDownloadDataTasks(). Use given") - Failure("Stub return value not specified for getDownloadDataTasks(). Use given") - } - return __value + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } } - - open func getDownloadDataTasksForCourse(_ courseId: String) -> [DownloadDataTask] { - addInvocation(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))) - let perform = methodPerformValue(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))) as? (String) -> Void - perform?(`courseId`) - var __value: [DownloadDataTask] - do { - __value = try methodReturnValue(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))).casted() - } catch { - onFatalFailure("Stub return value not specified for getDownloadDataTasksForCourse(_ courseId: String). Use given") - Failure("Stub return value not specified for getDownloadDataTasksForCourse(_ courseId: String). Use given") - } - return __value + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) } +} +// MARK: - CoreAnalytics - fileprivate enum MethodType { - case m_set__userId_userId(Parameter) - case m_getUserID - case m_publisher - case m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>) - case m_saveOfflineProgress__progress_progress(Parameter) - case m_loadProgress__for_blockID(Parameter) - case m_loadAllOfflineProgress - case m_deleteProgress__for_blockID(Parameter) - case m_deleteAllProgress - case m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>, Parameter) - case m_nextBlockForDownloading - case m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter, Parameter, Parameter) - case m_deleteDownloadDataTask__id_id(Parameter) - case m_saveDownloadDataTask__task(Parameter) - case m_downloadDataTask__for_blockId(Parameter) - case m_getDownloadDataTasks - case m_getDownloadDataTasksForCourse__courseId(Parameter) +open class CoreAnalyticsMock: CoreAnalytics, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } - static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { - case (.m_set__userId_userId(let lhsUserid), .m_set__userId_userId(let rhsUserid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUserid, rhs: rhsUserid, with: matcher), lhsUserid, rhsUserid, "userId")) - return Matcher.ComparisonResult(results) + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst - case (.m_getUserID, .m_getUserID): return .match + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? - case (.m_publisher, .m_publisher): return .match + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given - case (.m_addToDownloadQueue__tasks_tasks(let lhsTasks), .m_addToDownloadQueue__tasks_tasks(let rhsTasks)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTasks, rhs: rhsTasks, with: matcher), lhsTasks, rhsTasks, "tasks")) - return Matcher.ComparisonResult(results) + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } - case (.m_saveOfflineProgress__progress_progress(let lhsProgress), .m_saveOfflineProgress__progress_progress(let rhsProgress)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsProgress, rhs: rhsProgress, with: matcher), lhsProgress, rhsProgress, "progress")) - return Matcher.ComparisonResult(results) + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } - case (.m_loadProgress__for_blockID(let lhsBlockid), .m_loadProgress__for_blockID(let rhsBlockid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockID")) - return Matcher.ComparisonResult(results) - case (.m_loadAllOfflineProgress, .m_loadAllOfflineProgress): return .match - case (.m_deleteProgress__for_blockID(let lhsBlockid), .m_deleteProgress__for_blockID(let rhsBlockid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockID")) - return Matcher.ComparisonResult(results) - case (.m_deleteAllProgress, .m_deleteAllProgress): return .match - case (.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(let lhsBlocks, let lhsDownloadquality), .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(let rhsBlocks, let rhsDownloadquality)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDownloadquality, rhs: rhsDownloadquality, with: matcher), lhsDownloadquality, rhsDownloadquality, "downloadQuality")) - return Matcher.ComparisonResult(results) + open func trackEvent(_ event: AnalyticsEvent, parameters: [String: Any]?) { + addInvocation(.m_trackEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) + let perform = methodPerformValue(.m_trackEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, [String: Any]?) -> Void + perform?(`event`, `parameters`) + } - case (.m_nextBlockForDownloading, .m_nextBlockForDownloading): return .match + open func trackEvent(_ event: AnalyticsEvent, biValue: EventBIValue, parameters: [String: Any]?) { + addInvocation(.m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) + let perform = methodPerformValue(.m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void + perform?(`event`, `biValue`, `parameters`) + } - case (.m_updateDownloadState__id_idstate_stateresumeData_resumeData(let lhsId, let lhsState, let lhsResumedata), .m_updateDownloadState__id_idstate_stateresumeData_resumeData(let rhsId, let rhsState, let rhsResumedata)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsId, rhs: rhsId, with: matcher), lhsId, rhsId, "id")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsState, rhs: rhsState, with: matcher), lhsState, rhsState, "state")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsResumedata, rhs: rhsResumedata, with: matcher), lhsResumedata, rhsResumedata, "resumeData")) - return Matcher.ComparisonResult(results) + open func trackScreenEvent(_ event: AnalyticsEvent, parameters: [String: Any]?) { + addInvocation(.m_trackScreenEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) + let perform = methodPerformValue(.m_trackScreenEvent__eventparameters_parameters(Parameter.value(`event`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, [String: Any]?) -> Void + perform?(`event`, `parameters`) + } - case (.m_deleteDownloadDataTask__id_id(let lhsId), .m_deleteDownloadDataTask__id_id(let rhsId)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsId, rhs: rhsId, with: matcher), lhsId, rhsId, "id")) - return Matcher.ComparisonResult(results) + open func trackScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue, parameters: [String: Any]?) { + addInvocation(.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) + let perform = methodPerformValue(.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter.value(`event`), Parameter.value(`biValue`), Parameter<[String: Any]?>.value(`parameters`))) as? (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void + perform?(`event`, `biValue`, `parameters`) + } - case (.m_saveDownloadDataTask__task(let lhsTask), .m_saveDownloadDataTask__task(let rhsTask)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTask, rhs: rhsTask, with: matcher), lhsTask, rhsTask, "_ task")) - return Matcher.ComparisonResult(results) + open func appreview(_ event: AnalyticsEvent, biValue: EventBIValue, action: String?, rating: Int?) { + addInvocation(.m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter.value(`event`), Parameter.value(`biValue`), Parameter.value(`action`), Parameter.value(`rating`))) + let perform = methodPerformValue(.m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter.value(`event`), Parameter.value(`biValue`), Parameter.value(`action`), Parameter.value(`rating`))) as? (AnalyticsEvent, EventBIValue, String?, Int?) -> Void + perform?(`event`, `biValue`, `action`, `rating`) + } - case (.m_downloadDataTask__for_blockId(let lhsBlockid), .m_downloadDataTask__for_blockId(let rhsBlockid)): + open func videoQualityChanged(_ event: AnalyticsEvent, bivalue: EventBIValue, value: String, oldValue: String) { + addInvocation(.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter.value(`event`), Parameter.value(`bivalue`), Parameter.value(`value`), Parameter.value(`oldValue`))) + let perform = methodPerformValue(.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter.value(`event`), Parameter.value(`bivalue`), Parameter.value(`value`), Parameter.value(`oldValue`))) as? (AnalyticsEvent, EventBIValue, String, String) -> Void + perform?(`event`, `bivalue`, `value`, `oldValue`) + } + + open func trackEvent(_ event: AnalyticsEvent) { + addInvocation(.m_trackEvent__event(Parameter.value(`event`))) + let perform = methodPerformValue(.m_trackEvent__event(Parameter.value(`event`))) as? (AnalyticsEvent) -> Void + perform?(`event`) + } + + open func trackEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { + addInvocation(.m_trackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) + let perform = methodPerformValue(.m_trackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void + perform?(`event`, `biValue`) + } + + open func trackScreenEvent(_ event: AnalyticsEvent) { + addInvocation(.m_trackScreenEvent__event(Parameter.value(`event`))) + let perform = methodPerformValue(.m_trackScreenEvent__event(Parameter.value(`event`))) as? (AnalyticsEvent) -> Void + perform?(`event`) + } + + open func trackScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { + addInvocation(.m_trackScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) + let perform = methodPerformValue(.m_trackScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void + perform?(`event`, `biValue`) + } + + + fileprivate enum MethodType { + case m_trackEvent__eventparameters_parameters(Parameter, Parameter<[String: Any]?>) + case m_trackEvent__eventbiValue_biValueparameters_parameters(Parameter, Parameter, Parameter<[String: Any]?>) + case m_trackScreenEvent__eventparameters_parameters(Parameter, Parameter<[String: Any]?>) + case m_trackScreenEvent__eventbiValue_biValueparameters_parameters(Parameter, Parameter, Parameter<[String: Any]?>) + case m_appreview__eventbiValue_biValueaction_actionrating_rating(Parameter, Parameter, Parameter, Parameter) + case m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(Parameter, Parameter, Parameter, Parameter) + case m_trackEvent__event(Parameter) + case m_trackEvent__eventbiValue_biValue(Parameter, Parameter) + case m_trackScreenEvent__event(Parameter) + case m_trackScreenEvent__eventbiValue_biValue(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_trackEvent__eventparameters_parameters(let lhsEvent, let lhsParameters), .m_trackEvent__eventparameters_parameters(let rhsEvent, let rhsParameters)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockId")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) return Matcher.ComparisonResult(results) - case (.m_getDownloadDataTasks, .m_getDownloadDataTasks): return .match + case (.m_trackEvent__eventbiValue_biValueparameters_parameters(let lhsEvent, let lhsBivalue, let lhsParameters), .m_trackEvent__eventbiValue_biValueparameters_parameters(let rhsEvent, let rhsBivalue, let rhsParameters)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) + return Matcher.ComparisonResult(results) - case (.m_getDownloadDataTasksForCourse__courseId(let lhsCourseid), .m_getDownloadDataTasksForCourse__courseId(let rhsCourseid)): + case (.m_trackScreenEvent__eventparameters_parameters(let lhsEvent, let lhsParameters), .m_trackScreenEvent__eventparameters_parameters(let rhsEvent, let rhsParameters)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "_ courseId")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) + return Matcher.ComparisonResult(results) + + case (.m_trackScreenEvent__eventbiValue_biValueparameters_parameters(let lhsEvent, let lhsBivalue, let lhsParameters), .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(let rhsEvent, let rhsBivalue, let rhsParameters)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) + return Matcher.ComparisonResult(results) + + case (.m_appreview__eventbiValue_biValueaction_actionrating_rating(let lhsEvent, let lhsBivalue, let lhsAction, let lhsRating), .m_appreview__eventbiValue_biValueaction_actionrating_rating(let rhsEvent, let rhsBivalue, let rhsAction, let rhsRating)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsRating, rhs: rhsRating, with: matcher), lhsRating, rhsRating, "rating")) + return Matcher.ComparisonResult(results) + + case (.m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(let lhsEvent, let lhsBivalue, let lhsValue, let lhsOldvalue), .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(let rhsEvent, let rhsBivalue, let rhsValue, let rhsOldvalue)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "bivalue")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsValue, rhs: rhsValue, with: matcher), lhsValue, rhsValue, "value")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsOldvalue, rhs: rhsOldvalue, with: matcher), lhsOldvalue, rhsOldvalue, "oldValue")) + return Matcher.ComparisonResult(results) + + case (.m_trackEvent__event(let lhsEvent), .m_trackEvent__event(let rhsEvent)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + return Matcher.ComparisonResult(results) + + case (.m_trackEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_trackEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + return Matcher.ComparisonResult(results) + + case (.m_trackScreenEvent__event(let lhsEvent), .m_trackScreenEvent__event(let rhsEvent)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + return Matcher.ComparisonResult(results) + + case (.m_trackScreenEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_trackScreenEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) return Matcher.ComparisonResult(results) default: return .none } @@ -1835,44 +2255,30 @@ open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { func intValue() -> Int { switch self { - case let .m_set__userId_userId(p0): return p0.intValue - case .m_getUserID: return 0 - case .m_publisher: return 0 - case let .m_addToDownloadQueue__tasks_tasks(p0): return p0.intValue - case let .m_saveOfflineProgress__progress_progress(p0): return p0.intValue - case let .m_loadProgress__for_blockID(p0): return p0.intValue - case .m_loadAllOfflineProgress: return 0 - case let .m_deleteProgress__for_blockID(p0): return p0.intValue - case .m_deleteAllProgress: return 0 - case let .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(p0, p1): return p0.intValue + p1.intValue - case .m_nextBlockForDownloading: return 0 - case let .m_updateDownloadState__id_idstate_stateresumeData_resumeData(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue - case let .m_deleteDownloadDataTask__id_id(p0): return p0.intValue - case let .m_saveDownloadDataTask__task(p0): return p0.intValue - case let .m_downloadDataTask__for_blockId(p0): return p0.intValue - case .m_getDownloadDataTasks: return 0 - case let .m_getDownloadDataTasksForCourse__courseId(p0): return p0.intValue + case let .m_trackEvent__eventparameters_parameters(p0, p1): return p0.intValue + p1.intValue + case let .m_trackEvent__eventbiValue_biValueparameters_parameters(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case let .m_trackScreenEvent__eventparameters_parameters(p0, p1): return p0.intValue + p1.intValue + case let .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case let .m_appreview__eventbiValue_biValueaction_actionrating_rating(p0, p1, p2, p3): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + case let .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(p0, p1, p2, p3): return p0.intValue + p1.intValue + p2.intValue + p3.intValue + case let .m_trackEvent__event(p0): return p0.intValue + case let .m_trackEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue + case let .m_trackScreenEvent__event(p0): return p0.intValue + case let .m_trackScreenEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue } } func assertionName() -> String { switch self { - case .m_set__userId_userId: return ".set(userId:)" - case .m_getUserID: return ".getUserID()" - case .m_publisher: return ".publisher()" - case .m_addToDownloadQueue__tasks_tasks: return ".addToDownloadQueue(tasks:)" - case .m_saveOfflineProgress__progress_progress: return ".saveOfflineProgress(progress:)" - case .m_loadProgress__for_blockID: return ".loadProgress(for:)" - case .m_loadAllOfflineProgress: return ".loadAllOfflineProgress()" - case .m_deleteProgress__for_blockID: return ".deleteProgress(for:)" - case .m_deleteAllProgress: return ".deleteAllProgress()" - case .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality: return ".addToDownloadQueue(blocks:downloadQuality:)" - case .m_nextBlockForDownloading: return ".nextBlockForDownloading()" - case .m_updateDownloadState__id_idstate_stateresumeData_resumeData: return ".updateDownloadState(id:state:resumeData:)" - case .m_deleteDownloadDataTask__id_id: return ".deleteDownloadDataTask(id:)" - case .m_saveDownloadDataTask__task: return ".saveDownloadDataTask(_:)" - case .m_downloadDataTask__for_blockId: return ".downloadDataTask(for:)" - case .m_getDownloadDataTasks: return ".getDownloadDataTasks()" - case .m_getDownloadDataTasksForCourse__courseId: return ".getDownloadDataTasksForCourse(_:)" + case .m_trackEvent__eventparameters_parameters: return ".trackEvent(_:parameters:)" + case .m_trackEvent__eventbiValue_biValueparameters_parameters: return ".trackEvent(_:biValue:parameters:)" + case .m_trackScreenEvent__eventparameters_parameters: return ".trackScreenEvent(_:parameters:)" + case .m_trackScreenEvent__eventbiValue_biValueparameters_parameters: return ".trackScreenEvent(_:biValue:parameters:)" + case .m_appreview__eventbiValue_biValueaction_actionrating_rating: return ".appreview(_:biValue:action:rating:)" + case .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue: return ".videoQualityChanged(_:bivalue:value:oldValue:)" + case .m_trackEvent__event: return ".trackEvent(_:)" + case .m_trackEvent__eventbiValue_biValue: return ".trackEvent(_:biValue:)" + case .m_trackScreenEvent__event: return ".trackScreenEvent(_:)" + case .m_trackScreenEvent__eventbiValue_biValue: return ".trackScreenEvent(_:biValue:)" } } } @@ -1886,174 +2292,56 @@ open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { } - public static func getUserID(willReturn: Int?...) -> MethodStub { - return Given(method: .m_getUserID, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func publisher(willReturn: AnyPublisher...) -> MethodStub { - return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func loadProgress(for blockID: Parameter, willReturn: OfflineProgress?...) -> MethodStub { - return Given(method: .m_loadProgress__for_blockID(`blockID`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func loadAllOfflineProgress(willReturn: [OfflineProgress]...) -> MethodStub { - return Given(method: .m_loadAllOfflineProgress, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + + public struct Verify { + fileprivate var method: MethodType + + public static func trackEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackEvent__eventparameters_parameters(`event`, `parameters`))} + public static func trackEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`))} + public static func trackScreenEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackScreenEvent__eventparameters_parameters(`event`, `parameters`))} + public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>) -> Verify { return Verify(method: .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`))} + public static func appreview(_ event: Parameter, biValue: Parameter, action: Parameter, rating: Parameter) -> Verify { return Verify(method: .m_appreview__eventbiValue_biValueaction_actionrating_rating(`event`, `biValue`, `action`, `rating`))} + public static func videoQualityChanged(_ event: Parameter, bivalue: Parameter, value: Parameter, oldValue: Parameter) -> Verify { return Verify(method: .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(`event`, `bivalue`, `value`, `oldValue`))} + public static func trackEvent(_ event: Parameter) -> Verify { return Verify(method: .m_trackEvent__event(`event`))} + public static func trackEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_trackEvent__eventbiValue_biValue(`event`, `biValue`))} + public static func trackScreenEvent(_ event: Parameter) -> Verify { return Verify(method: .m_trackScreenEvent__event(`event`))} + public static func trackScreenEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_trackScreenEvent__eventbiValue_biValue(`event`, `biValue`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func trackEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, [String: Any]?) -> Void) -> Perform { + return Perform(method: .m_trackEvent__eventparameters_parameters(`event`, `parameters`), performs: perform) } - public static func nextBlockForDownloading(willReturn: DownloadDataTask?...) -> MethodStub { - return Given(method: .m_nextBlockForDownloading, products: willReturn.map({ StubProduct.return($0 as Any) })) + public static func trackEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void) -> Perform { + return Perform(method: .m_trackEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`), performs: perform) } - public static func downloadDataTask(for blockId: Parameter, willReturn: DownloadDataTask?...) -> MethodStub { - return Given(method: .m_downloadDataTask__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + public static func trackScreenEvent(_ event: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, [String: Any]?) -> Void) -> Perform { + return Perform(method: .m_trackScreenEvent__eventparameters_parameters(`event`, `parameters`), performs: perform) } - public static func getDownloadDataTasks(willReturn: [DownloadDataTask]...) -> MethodStub { - return Given(method: .m_getDownloadDataTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) + public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, parameters: Parameter<[String: Any]?>, perform: @escaping (AnalyticsEvent, EventBIValue, [String: Any]?) -> Void) -> Perform { + return Perform(method: .m_trackScreenEvent__eventbiValue_biValueparameters_parameters(`event`, `biValue`, `parameters`), performs: perform) } - public static func getDownloadDataTasksForCourse(_ courseId: Parameter, willReturn: [DownloadDataTask]...) -> MethodStub { - return Given(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + public static func appreview(_ event: Parameter, biValue: Parameter, action: Parameter, rating: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue, String?, Int?) -> Void) -> Perform { + return Perform(method: .m_appreview__eventbiValue_biValueaction_actionrating_rating(`event`, `biValue`, `action`, `rating`), performs: perform) } - public static func getUserID(willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [Int?] = [] - let given: Given = { return Given(method: .m_getUserID, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (Int?).self) - willProduce(stubber) - return given + public static func videoQualityChanged(_ event: Parameter, bivalue: Parameter, value: Parameter, oldValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue, String, String) -> Void) -> Perform { + return Perform(method: .m_videoQualityChanged__eventbivalue_bivaluevalue_valueoldValue_oldValue(`event`, `bivalue`, `value`, `oldValue`), performs: perform) } - public static func publisher(willProduce: (Stubber>) -> Void) -> MethodStub { - let willReturn: [AnyPublisher] = [] - let given: Given = { return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (AnyPublisher).self) - willProduce(stubber) - return given + public static func trackEvent(_ event: Parameter, perform: @escaping (AnalyticsEvent) -> Void) -> Perform { + return Perform(method: .m_trackEvent__event(`event`), performs: perform) } - public static func loadProgress(for blockID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [OfflineProgress?] = [] - let given: Given = { return Given(method: .m_loadProgress__for_blockID(`blockID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (OfflineProgress?).self) - willProduce(stubber) - return given + public static func trackEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { + return Perform(method: .m_trackEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) } - public static func loadAllOfflineProgress(willProduce: (Stubber<[OfflineProgress]>) -> Void) -> MethodStub { - let willReturn: [[OfflineProgress]] = [] - let given: Given = { return Given(method: .m_loadAllOfflineProgress, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([OfflineProgress]).self) - willProduce(stubber) - return given + public static func trackScreenEvent(_ event: Parameter, perform: @escaping (AnalyticsEvent) -> Void) -> Perform { + return Perform(method: .m_trackScreenEvent__event(`event`), performs: perform) } - public static func nextBlockForDownloading(willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [DownloadDataTask?] = [] - let given: Given = { return Given(method: .m_nextBlockForDownloading, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (DownloadDataTask?).self) - willProduce(stubber) - return given - } - public static func downloadDataTask(for blockId: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [DownloadDataTask?] = [] - let given: Given = { return Given(method: .m_downloadDataTask__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (DownloadDataTask?).self) - willProduce(stubber) - return given - } - public static func getDownloadDataTasks(willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { - let willReturn: [[DownloadDataTask]] = [] - let given: Given = { return Given(method: .m_getDownloadDataTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([DownloadDataTask]).self) - willProduce(stubber) - return given - } - public static func getDownloadDataTasksForCourse(_ courseId: Parameter, willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { - let willReturn: [[DownloadDataTask]] = [] - let given: Given = { return Given(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([DownloadDataTask]).self) - willProduce(stubber) - return given - } - public static func deleteDownloadDataTask(id: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_deleteDownloadDataTask__id_id(`id`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func deleteDownloadDataTask(id: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_deleteDownloadDataTask__id_id(`id`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - } - - public struct Verify { - fileprivate var method: MethodType - - public static func set(userId: Parameter) -> Verify { return Verify(method: .m_set__userId_userId(`userId`))} - public static func getUserID() -> Verify { return Verify(method: .m_getUserID)} - public static func publisher() -> Verify { return Verify(method: .m_publisher)} - public static func addToDownloadQueue(tasks: Parameter<[DownloadDataTask]>) -> Verify { return Verify(method: .m_addToDownloadQueue__tasks_tasks(`tasks`))} - public static func saveOfflineProgress(progress: Parameter) -> Verify { return Verify(method: .m_saveOfflineProgress__progress_progress(`progress`))} - public static func loadProgress(for blockID: Parameter) -> Verify { return Verify(method: .m_loadProgress__for_blockID(`blockID`))} - public static func loadAllOfflineProgress() -> Verify { return Verify(method: .m_loadAllOfflineProgress)} - public static func deleteProgress(for blockID: Parameter) -> Verify { return Verify(method: .m_deleteProgress__for_blockID(`blockID`))} - public static func deleteAllProgress() -> Verify { return Verify(method: .m_deleteAllProgress)} - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, downloadQuality: Parameter) -> Verify { return Verify(method: .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(`blocks`, `downloadQuality`))} - public static func nextBlockForDownloading() -> Verify { return Verify(method: .m_nextBlockForDownloading)} - public static func updateDownloadState(id: Parameter, state: Parameter, resumeData: Parameter) -> Verify { return Verify(method: .m_updateDownloadState__id_idstate_stateresumeData_resumeData(`id`, `state`, `resumeData`))} - public static func deleteDownloadDataTask(id: Parameter) -> Verify { return Verify(method: .m_deleteDownloadDataTask__id_id(`id`))} - public static func saveDownloadDataTask(_ task: Parameter) -> Verify { return Verify(method: .m_saveDownloadDataTask__task(`task`))} - public static func downloadDataTask(for blockId: Parameter) -> Verify { return Verify(method: .m_downloadDataTask__for_blockId(`blockId`))} - public static func getDownloadDataTasks() -> Verify { return Verify(method: .m_getDownloadDataTasks)} - public static func getDownloadDataTasksForCourse(_ courseId: Parameter) -> Verify { return Verify(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`))} - } - - public struct Perform { - fileprivate var method: MethodType - var performs: Any - - public static func set(userId: Parameter, perform: @escaping (Int) -> Void) -> Perform { - return Perform(method: .m_set__userId_userId(`userId`), performs: perform) - } - public static func getUserID(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getUserID, performs: perform) - } - public static func publisher(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_publisher, performs: perform) - } - public static func addToDownloadQueue(tasks: Parameter<[DownloadDataTask]>, perform: @escaping ([DownloadDataTask]) -> Void) -> Perform { - return Perform(method: .m_addToDownloadQueue__tasks_tasks(`tasks`), performs: perform) - } - public static func saveOfflineProgress(progress: Parameter, perform: @escaping (OfflineProgress) -> Void) -> Perform { - return Perform(method: .m_saveOfflineProgress__progress_progress(`progress`), performs: perform) - } - public static func loadProgress(for blockID: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_loadProgress__for_blockID(`blockID`), performs: perform) - } - public static func loadAllOfflineProgress(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_loadAllOfflineProgress, performs: perform) - } - public static func deleteProgress(for blockID: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_deleteProgress__for_blockID(`blockID`), performs: perform) - } - public static func deleteAllProgress(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_deleteAllProgress, performs: perform) - } - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, downloadQuality: Parameter, perform: @escaping ([CourseBlock], DownloadQuality) -> Void) -> Perform { - return Perform(method: .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(`blocks`, `downloadQuality`), performs: perform) - } - public static func nextBlockForDownloading(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_nextBlockForDownloading, performs: perform) - } - public static func updateDownloadState(id: Parameter, state: Parameter, resumeData: Parameter, perform: @escaping (String, DownloadState, Data?) -> Void) -> Perform { - return Perform(method: .m_updateDownloadState__id_idstate_stateresumeData_resumeData(`id`, `state`, `resumeData`), performs: perform) - } - public static func deleteDownloadDataTask(id: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_deleteDownloadDataTask__id_id(`id`), performs: perform) - } - public static func saveDownloadDataTask(_ task: Parameter, perform: @escaping (DownloadDataTask) -> Void) -> Perform { - return Perform(method: .m_saveDownloadDataTask__task(`task`), performs: perform) - } - public static func downloadDataTask(for blockId: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_downloadDataTask__for_blockId(`blockId`), performs: perform) - } - public static func getDownloadDataTasks(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getDownloadDataTasks, performs: perform) - } - public static func getDownloadDataTasksForCourse(_ courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), performs: perform) + public static func trackScreenEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { + return Perform(method: .m_trackScreenEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) } } @@ -2130,9 +2418,9 @@ open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { } } -// MARK: - CoreStorage +// MARK: - CorePersistenceProtocol -open class CoreStorageMock: CoreStorage, Mock { +open class CorePersistenceProtocolMock: CorePersistenceProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -2170,877 +2458,1742 @@ open class CoreStorageMock: CoreStorage, Mock { if scopes.contains(.perform) { methodPerformValues = [] } } - public var accessToken: String? { - get { invocations.append(.p_accessToken_get); return __p_accessToken ?? optionalGivenGetterValue(.p_accessToken_get, "CoreStorageMock - stub value for accessToken was not defined") } - set { invocations.append(.p_accessToken_set(.value(newValue))); __p_accessToken = newValue } - } - private var __p_accessToken: (String)? - - public var refreshToken: String? { - get { invocations.append(.p_refreshToken_get); return __p_refreshToken ?? optionalGivenGetterValue(.p_refreshToken_get, "CoreStorageMock - stub value for refreshToken was not defined") } - set { invocations.append(.p_refreshToken_set(.value(newValue))); __p_refreshToken = newValue } - } - private var __p_refreshToken: (String)? - - public var pushToken: String? { - get { invocations.append(.p_pushToken_get); return __p_pushToken ?? optionalGivenGetterValue(.p_pushToken_get, "CoreStorageMock - stub value for pushToken was not defined") } - set { invocations.append(.p_pushToken_set(.value(newValue))); __p_pushToken = newValue } - } - private var __p_pushToken: (String)? - - public var appleSignFullName: String? { - get { invocations.append(.p_appleSignFullName_get); return __p_appleSignFullName ?? optionalGivenGetterValue(.p_appleSignFullName_get, "CoreStorageMock - stub value for appleSignFullName was not defined") } - set { invocations.append(.p_appleSignFullName_set(.value(newValue))); __p_appleSignFullName = newValue } - } - private var __p_appleSignFullName: (String)? - - public var appleSignEmail: String? { - get { invocations.append(.p_appleSignEmail_get); return __p_appleSignEmail ?? optionalGivenGetterValue(.p_appleSignEmail_get, "CoreStorageMock - stub value for appleSignEmail was not defined") } - set { invocations.append(.p_appleSignEmail_set(.value(newValue))); __p_appleSignEmail = newValue } - } - private var __p_appleSignEmail: (String)? - public var cookiesDate: Date? { - get { invocations.append(.p_cookiesDate_get); return __p_cookiesDate ?? optionalGivenGetterValue(.p_cookiesDate_get, "CoreStorageMock - stub value for cookiesDate was not defined") } - set { invocations.append(.p_cookiesDate_set(.value(newValue))); __p_cookiesDate = newValue } - } - private var __p_cookiesDate: (Date)? - public var reviewLastShownVersion: String? { - get { invocations.append(.p_reviewLastShownVersion_get); return __p_reviewLastShownVersion ?? optionalGivenGetterValue(.p_reviewLastShownVersion_get, "CoreStorageMock - stub value for reviewLastShownVersion was not defined") } - set { invocations.append(.p_reviewLastShownVersion_set(.value(newValue))); __p_reviewLastShownVersion = newValue } - } - private var __p_reviewLastShownVersion: (String)? - public var lastReviewDate: Date? { - get { invocations.append(.p_lastReviewDate_get); return __p_lastReviewDate ?? optionalGivenGetterValue(.p_lastReviewDate_get, "CoreStorageMock - stub value for lastReviewDate was not defined") } - set { invocations.append(.p_lastReviewDate_set(.value(newValue))); __p_lastReviewDate = newValue } - } - private var __p_lastReviewDate: (Date)? - public var user: DataLayer.User? { - get { invocations.append(.p_user_get); return __p_user ?? optionalGivenGetterValue(.p_user_get, "CoreStorageMock - stub value for user was not defined") } - set { invocations.append(.p_user_set(.value(newValue))); __p_user = newValue } - } - private var __p_user: (DataLayer.User)? + open func set(userId: Int) { + addInvocation(.m_set__userId_userId(Parameter.value(`userId`))) + let perform = methodPerformValue(.m_set__userId_userId(Parameter.value(`userId`))) as? (Int) -> Void + perform?(`userId`) + } - public var userSettings: UserSettings? { - get { invocations.append(.p_userSettings_get); return __p_userSettings ?? optionalGivenGetterValue(.p_userSettings_get, "CoreStorageMock - stub value for userSettings was not defined") } - set { invocations.append(.p_userSettings_set(.value(newValue))); __p_userSettings = newValue } - } - private var __p_userSettings: (UserSettings)? + open func getUserID() -> Int? { + addInvocation(.m_getUserID) + let perform = methodPerformValue(.m_getUserID) as? () -> Void + perform?() + var __value: Int? = nil + do { + __value = try methodReturnValue(.m_getUserID).casted() + } catch { + // do nothing + } + return __value + } - public var resetAppSupportDirectoryUserData: Bool? { - get { invocations.append(.p_resetAppSupportDirectoryUserData_get); return __p_resetAppSupportDirectoryUserData ?? optionalGivenGetterValue(.p_resetAppSupportDirectoryUserData_get, "CoreStorageMock - stub value for resetAppSupportDirectoryUserData was not defined") } - set { invocations.append(.p_resetAppSupportDirectoryUserData_set(.value(newValue))); __p_resetAppSupportDirectoryUserData = newValue } - } - private var __p_resetAppSupportDirectoryUserData: (Bool)? + open func publisher() -> AnyPublisher { + addInvocation(.m_publisher) + let perform = methodPerformValue(.m_publisher) as? () -> Void + perform?() + var __value: AnyPublisher + do { + __value = try methodReturnValue(.m_publisher).casted() + } catch { + onFatalFailure("Stub return value not specified for publisher(). Use given") + Failure("Stub return value not specified for publisher(). Use given") + } + return __value + } - public var useRelativeDates: Bool { - get { invocations.append(.p_useRelativeDates_get); return __p_useRelativeDates ?? givenGetterValue(.p_useRelativeDates_get, "CoreStorageMock - stub value for useRelativeDates was not defined") } - set { invocations.append(.p_useRelativeDates_set(.value(newValue))); __p_useRelativeDates = newValue } - } - private var __p_useRelativeDates: (Bool)? + open func addToDownloadQueue(tasks: [DownloadDataTask]) { + addInvocation(.m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>.value(`tasks`))) + let perform = methodPerformValue(.m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>.value(`tasks`))) as? ([DownloadDataTask]) -> Void + perform?(`tasks`) + } + open func saveOfflineProgress(progress: OfflineProgress) { + addInvocation(.m_saveOfflineProgress__progress_progress(Parameter.value(`progress`))) + let perform = methodPerformValue(.m_saveOfflineProgress__progress_progress(Parameter.value(`progress`))) as? (OfflineProgress) -> Void + perform?(`progress`) + } + open func loadProgress(for blockID: String) -> OfflineProgress? { + addInvocation(.m_loadProgress__for_blockID(Parameter.value(`blockID`))) + let perform = methodPerformValue(.m_loadProgress__for_blockID(Parameter.value(`blockID`))) as? (String) -> Void + perform?(`blockID`) + var __value: OfflineProgress? = nil + do { + __value = try methodReturnValue(.m_loadProgress__for_blockID(Parameter.value(`blockID`))).casted() + } catch { + // do nothing + } + return __value + } + open func loadAllOfflineProgress() -> [OfflineProgress] { + addInvocation(.m_loadAllOfflineProgress) + let perform = methodPerformValue(.m_loadAllOfflineProgress) as? () -> Void + perform?() + var __value: [OfflineProgress] + do { + __value = try methodReturnValue(.m_loadAllOfflineProgress).casted() + } catch { + onFatalFailure("Stub return value not specified for loadAllOfflineProgress(). Use given") + Failure("Stub return value not specified for loadAllOfflineProgress(). Use given") + } + return __value + } + open func deleteProgress(for blockID: String) { + addInvocation(.m_deleteProgress__for_blockID(Parameter.value(`blockID`))) + let perform = methodPerformValue(.m_deleteProgress__for_blockID(Parameter.value(`blockID`))) as? (String) -> Void + perform?(`blockID`) + } - open func clear() { - addInvocation(.m_clear) - let perform = methodPerformValue(.m_clear) as? () -> Void + open func deleteAllProgress() { + addInvocation(.m_deleteAllProgress) + let perform = methodPerformValue(.m_deleteAllProgress) as? () -> Void perform?() } + open func addToDownloadQueue(blocks: [CourseBlock], downloadQuality: DownloadQuality) { + addInvocation(.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>.value(`blocks`), Parameter.value(`downloadQuality`))) + let perform = methodPerformValue(.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>.value(`blocks`), Parameter.value(`downloadQuality`))) as? ([CourseBlock], DownloadQuality) -> Void + perform?(`blocks`, `downloadQuality`) + } - fileprivate enum MethodType { - case m_clear - case p_accessToken_get - case p_accessToken_set(Parameter) - case p_refreshToken_get - case p_refreshToken_set(Parameter) - case p_pushToken_get - case p_pushToken_set(Parameter) - case p_appleSignFullName_get - case p_appleSignFullName_set(Parameter) - case p_appleSignEmail_get - case p_appleSignEmail_set(Parameter) - case p_cookiesDate_get - case p_cookiesDate_set(Parameter) - case p_reviewLastShownVersion_get - case p_reviewLastShownVersion_set(Parameter) - case p_lastReviewDate_get - case p_lastReviewDate_set(Parameter) - case p_user_get - case p_user_set(Parameter) - case p_userSettings_get - case p_userSettings_set(Parameter) - case p_resetAppSupportDirectoryUserData_get - case p_resetAppSupportDirectoryUserData_set(Parameter) - case p_useRelativeDates_get - case p_useRelativeDates_set(Parameter) - - static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { - case (.m_clear, .m_clear): return .match - case (.p_accessToken_get,.p_accessToken_get): return Matcher.ComparisonResult.match - case (.p_accessToken_set(let left),.p_accessToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_refreshToken_get,.p_refreshToken_get): return Matcher.ComparisonResult.match - case (.p_refreshToken_set(let left),.p_refreshToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_pushToken_get,.p_pushToken_get): return Matcher.ComparisonResult.match - case (.p_pushToken_set(let left),.p_pushToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_appleSignFullName_get,.p_appleSignFullName_get): return Matcher.ComparisonResult.match - case (.p_appleSignFullName_set(let left),.p_appleSignFullName_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_appleSignEmail_get,.p_appleSignEmail_get): return Matcher.ComparisonResult.match - case (.p_appleSignEmail_set(let left),.p_appleSignEmail_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_cookiesDate_get,.p_cookiesDate_get): return Matcher.ComparisonResult.match - case (.p_cookiesDate_set(let left),.p_cookiesDate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_reviewLastShownVersion_get,.p_reviewLastShownVersion_get): return Matcher.ComparisonResult.match - case (.p_reviewLastShownVersion_set(let left),.p_reviewLastShownVersion_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_lastReviewDate_get,.p_lastReviewDate_get): return Matcher.ComparisonResult.match - case (.p_lastReviewDate_set(let left),.p_lastReviewDate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_user_get,.p_user_get): return Matcher.ComparisonResult.match - case (.p_user_set(let left),.p_user_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_userSettings_get,.p_userSettings_get): return Matcher.ComparisonResult.match - case (.p_userSettings_set(let left),.p_userSettings_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_resetAppSupportDirectoryUserData_get,.p_resetAppSupportDirectoryUserData_get): return Matcher.ComparisonResult.match - case (.p_resetAppSupportDirectoryUserData_set(let left),.p_resetAppSupportDirectoryUserData_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - case (.p_useRelativeDates_get,.p_useRelativeDates_get): return Matcher.ComparisonResult.match - case (.p_useRelativeDates_set(let left),.p_useRelativeDates_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) - default: return .none - } - } - - func intValue() -> Int { - switch self { - case .m_clear: return 0 - case .p_accessToken_get: return 0 - case .p_accessToken_set(let newValue): return newValue.intValue - case .p_refreshToken_get: return 0 - case .p_refreshToken_set(let newValue): return newValue.intValue - case .p_pushToken_get: return 0 - case .p_pushToken_set(let newValue): return newValue.intValue - case .p_appleSignFullName_get: return 0 - case .p_appleSignFullName_set(let newValue): return newValue.intValue - case .p_appleSignEmail_get: return 0 - case .p_appleSignEmail_set(let newValue): return newValue.intValue - case .p_cookiesDate_get: return 0 - case .p_cookiesDate_set(let newValue): return newValue.intValue - case .p_reviewLastShownVersion_get: return 0 - case .p_reviewLastShownVersion_set(let newValue): return newValue.intValue - case .p_lastReviewDate_get: return 0 - case .p_lastReviewDate_set(let newValue): return newValue.intValue - case .p_user_get: return 0 - case .p_user_set(let newValue): return newValue.intValue - case .p_userSettings_get: return 0 - case .p_userSettings_set(let newValue): return newValue.intValue - case .p_resetAppSupportDirectoryUserData_get: return 0 - case .p_resetAppSupportDirectoryUserData_set(let newValue): return newValue.intValue - case .p_useRelativeDates_get: return 0 - case .p_useRelativeDates_set(let newValue): return newValue.intValue - } - } - func assertionName() -> String { - switch self { - case .m_clear: return ".clear()" - case .p_accessToken_get: return "[get] .accessToken" - case .p_accessToken_set: return "[set] .accessToken" - case .p_refreshToken_get: return "[get] .refreshToken" - case .p_refreshToken_set: return "[set] .refreshToken" - case .p_pushToken_get: return "[get] .pushToken" - case .p_pushToken_set: return "[set] .pushToken" - case .p_appleSignFullName_get: return "[get] .appleSignFullName" - case .p_appleSignFullName_set: return "[set] .appleSignFullName" - case .p_appleSignEmail_get: return "[get] .appleSignEmail" - case .p_appleSignEmail_set: return "[set] .appleSignEmail" - case .p_cookiesDate_get: return "[get] .cookiesDate" - case .p_cookiesDate_set: return "[set] .cookiesDate" - case .p_reviewLastShownVersion_get: return "[get] .reviewLastShownVersion" - case .p_reviewLastShownVersion_set: return "[set] .reviewLastShownVersion" - case .p_lastReviewDate_get: return "[get] .lastReviewDate" - case .p_lastReviewDate_set: return "[set] .lastReviewDate" - case .p_user_get: return "[get] .user" - case .p_user_set: return "[set] .user" - case .p_userSettings_get: return "[get] .userSettings" - case .p_userSettings_set: return "[set] .userSettings" - case .p_resetAppSupportDirectoryUserData_get: return "[get] .resetAppSupportDirectoryUserData" - case .p_resetAppSupportDirectoryUserData_set: return "[set] .resetAppSupportDirectoryUserData" - case .p_useRelativeDates_get: return "[get] .useRelativeDates" - case .p_useRelativeDates_set: return "[set] .useRelativeDates" - } - } + open func nextBlockForDownloading() -> DownloadDataTask? { + addInvocation(.m_nextBlockForDownloading) + let perform = methodPerformValue(.m_nextBlockForDownloading) as? () -> Void + perform?() + var __value: DownloadDataTask? = nil + do { + __value = try methodReturnValue(.m_nextBlockForDownloading).casted() + } catch { + // do nothing + } + return __value } - open class Given: StubbedMethod { - fileprivate var method: MethodType - - private init(method: MethodType, products: [StubProduct]) { - self.method = method - super.init(products) - } - - public static func accessToken(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_accessToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func refreshToken(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_refreshToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func pushToken(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_pushToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func appleSignFullName(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_appleSignFullName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func appleSignEmail(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_appleSignEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func cookiesDate(getter defaultValue: Date?...) -> PropertyStub { - return Given(method: .p_cookiesDate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func reviewLastShownVersion(getter defaultValue: String?...) -> PropertyStub { - return Given(method: .p_reviewLastShownVersion_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func lastReviewDate(getter defaultValue: Date?...) -> PropertyStub { - return Given(method: .p_lastReviewDate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func user(getter defaultValue: DataLayer.User?...) -> PropertyStub { - return Given(method: .p_user_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func userSettings(getter defaultValue: UserSettings?...) -> PropertyStub { - return Given(method: .p_userSettings_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func resetAppSupportDirectoryUserData(getter defaultValue: Bool?...) -> PropertyStub { - return Given(method: .p_resetAppSupportDirectoryUserData_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - public static func useRelativeDates(getter defaultValue: Bool...) -> PropertyStub { - return Given(method: .p_useRelativeDates_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - + open func updateDownloadState(id: String, state: DownloadState, resumeData: Data?) { + addInvocation(.m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter.value(`id`), Parameter.value(`state`), Parameter.value(`resumeData`))) + let perform = methodPerformValue(.m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter.value(`id`), Parameter.value(`state`), Parameter.value(`resumeData`))) as? (String, DownloadState, Data?) -> Void + perform?(`id`, `state`, `resumeData`) } - public struct Verify { - fileprivate var method: MethodType - - public static func clear() -> Verify { return Verify(method: .m_clear)} - public static var accessToken: Verify { return Verify(method: .p_accessToken_get) } - public static func accessToken(set newValue: Parameter) -> Verify { return Verify(method: .p_accessToken_set(newValue)) } - public static var refreshToken: Verify { return Verify(method: .p_refreshToken_get) } - public static func refreshToken(set newValue: Parameter) -> Verify { return Verify(method: .p_refreshToken_set(newValue)) } - public static var pushToken: Verify { return Verify(method: .p_pushToken_get) } - public static func pushToken(set newValue: Parameter) -> Verify { return Verify(method: .p_pushToken_set(newValue)) } - public static var appleSignFullName: Verify { return Verify(method: .p_appleSignFullName_get) } - public static func appleSignFullName(set newValue: Parameter) -> Verify { return Verify(method: .p_appleSignFullName_set(newValue)) } - public static var appleSignEmail: Verify { return Verify(method: .p_appleSignEmail_get) } - public static func appleSignEmail(set newValue: Parameter) -> Verify { return Verify(method: .p_appleSignEmail_set(newValue)) } - public static var cookiesDate: Verify { return Verify(method: .p_cookiesDate_get) } - public static func cookiesDate(set newValue: Parameter) -> Verify { return Verify(method: .p_cookiesDate_set(newValue)) } - public static var reviewLastShownVersion: Verify { return Verify(method: .p_reviewLastShownVersion_get) } - public static func reviewLastShownVersion(set newValue: Parameter) -> Verify { return Verify(method: .p_reviewLastShownVersion_set(newValue)) } - public static var lastReviewDate: Verify { return Verify(method: .p_lastReviewDate_get) } - public static func lastReviewDate(set newValue: Parameter) -> Verify { return Verify(method: .p_lastReviewDate_set(newValue)) } - public static var user: Verify { return Verify(method: .p_user_get) } - public static func user(set newValue: Parameter) -> Verify { return Verify(method: .p_user_set(newValue)) } - public static var userSettings: Verify { return Verify(method: .p_userSettings_get) } - public static func userSettings(set newValue: Parameter) -> Verify { return Verify(method: .p_userSettings_set(newValue)) } - public static var resetAppSupportDirectoryUserData: Verify { return Verify(method: .p_resetAppSupportDirectoryUserData_get) } - public static func resetAppSupportDirectoryUserData(set newValue: Parameter) -> Verify { return Verify(method: .p_resetAppSupportDirectoryUserData_set(newValue)) } - public static var useRelativeDates: Verify { return Verify(method: .p_useRelativeDates_get) } - public static func useRelativeDates(set newValue: Parameter) -> Verify { return Verify(method: .p_useRelativeDates_set(newValue)) } + open func deleteDownloadDataTask(id: String) throws { + addInvocation(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))) + let perform = methodPerformValue(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))) as? (String) -> Void + perform?(`id`) + do { + _ = try methodReturnValue(.m_deleteDownloadDataTask__id_id(Parameter.value(`id`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } } - public struct Perform { - fileprivate var method: MethodType - var performs: Any - - public static func clear(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_clear, performs: perform) - } + open func saveDownloadDataTask(_ task: DownloadDataTask) { + addInvocation(.m_saveDownloadDataTask__task(Parameter.value(`task`))) + let perform = methodPerformValue(.m_saveDownloadDataTask__task(Parameter.value(`task`))) as? (DownloadDataTask) -> Void + perform?(`task`) } - public func given(_ method: Given) { - methodReturnValues.append(method) + open func downloadDataTask(for blockId: String) -> DownloadDataTask? { + addInvocation(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))) + let perform = methodPerformValue(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))) as? (String) -> Void + perform?(`blockId`) + var __value: DownloadDataTask? = nil + do { + __value = try methodReturnValue(.m_downloadDataTask__for_blockId(Parameter.value(`blockId`))).casted() + } catch { + // do nothing + } + return __value } - public func perform(_ method: Perform) { - methodPerformValues.append(method) - methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + open func getDownloadDataTasks() -> [DownloadDataTask] { + addInvocation(.m_getDownloadDataTasks) + let perform = methodPerformValue(.m_getDownloadDataTasks) as? () -> Void + perform?() + var __value: [DownloadDataTask] + do { + __value = try methodReturnValue(.m_getDownloadDataTasks).casted() + } catch { + onFatalFailure("Stub return value not specified for getDownloadDataTasks(). Use given") + Failure("Stub return value not specified for getDownloadDataTasks(). Use given") + } + return __value } - public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { - let fullMatches = matchingCalls(method, file: file, line: line) - let success = count.matches(fullMatches) - let assertionName = method.method.assertionName() - let feedback: String = { - guard !success else { return "" } - return Utils.closestCallsMessage( - for: self.invocations.map { invocation in - matcher.set(file: file, line: line) - defer { matcher.clearFileAndLine() } - return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) - }, - name: assertionName - ) - }() - MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + open func getDownloadDataTasksForCourse(_ courseId: String) -> [DownloadDataTask] { + addInvocation(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))) + let perform = methodPerformValue(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))) as? (String) -> Void + perform?(`courseId`) + var __value: [DownloadDataTask] + do { + __value = try methodReturnValue(.m_getDownloadDataTasksForCourse__courseId(Parameter.value(`courseId`))).casted() + } catch { + onFatalFailure("Stub return value not specified for getDownloadDataTasksForCourse(_ courseId: String). Use given") + Failure("Stub return value not specified for getDownloadDataTasksForCourse(_ courseId: String). Use given") + } + return __value } - private func addInvocation(_ call: MethodType) { - self.queue.sync { invocations.append(call) } - } - private func methodReturnValue(_ method: MethodType) throws -> StubProduct { - matcher.set(file: self.file, line: self.line) - defer { matcher.clearFileAndLine() } - let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) - let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) - guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } - return product - } - private func methodPerformValue(_ method: MethodType) -> Any? { - matcher.set(file: self.file, line: self.line) - defer { matcher.clearFileAndLine() } - let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } - return matched?.performs - } - private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { - matcher.set(file: file ?? self.file, line: line ?? self.line) - defer { matcher.clearFileAndLine() } - return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } - } - private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { - return matchingCalls(method.method, file: file, line: line).count - } - private func givenGetterValue(_ method: MethodType, _ message: String) -> T { - do { - return try methodReturnValue(method).casted() - } catch { - onFatalFailure(message) - Failure(message) - } - } - private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { - do { - return try methodReturnValue(method).casted() - } catch { - return nil - } - } - private func onFatalFailure(_ message: String) { - guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully - SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) - } -} -// MARK: - DownloadManagerProtocol + fileprivate enum MethodType { + case m_set__userId_userId(Parameter) + case m_getUserID + case m_publisher + case m_addToDownloadQueue__tasks_tasks(Parameter<[DownloadDataTask]>) + case m_saveOfflineProgress__progress_progress(Parameter) + case m_loadProgress__for_blockID(Parameter) + case m_loadAllOfflineProgress + case m_deleteProgress__for_blockID(Parameter) + case m_deleteAllProgress + case m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(Parameter<[CourseBlock]>, Parameter) + case m_nextBlockForDownloading + case m_updateDownloadState__id_idstate_stateresumeData_resumeData(Parameter, Parameter, Parameter) + case m_deleteDownloadDataTask__id_id(Parameter) + case m_saveDownloadDataTask__task(Parameter) + case m_downloadDataTask__for_blockId(Parameter) + case m_getDownloadDataTasks + case m_getDownloadDataTasksForCourse__courseId(Parameter) -open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { - public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { - SwiftyMockyTestObserver.setup() - self.sequencingPolicy = sequencingPolicy - self.stubbingPolicy = stubbingPolicy - self.file = file - self.line = line - } + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_set__userId_userId(let lhsUserid), .m_set__userId_userId(let rhsUserid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUserid, rhs: rhsUserid, with: matcher), lhsUserid, rhsUserid, "userId")) + return Matcher.ComparisonResult(results) - var matcher: Matcher = Matcher.default - var stubbingPolicy: StubbingPolicy = .wrap - var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + case (.m_getUserID, .m_getUserID): return .match - private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) - private var invocations: [MethodType] = [] - private var methodReturnValues: [Given] = [] - private var methodPerformValues: [Perform] = [] - private var file: StaticString? - private var line: UInt? + case (.m_publisher, .m_publisher): return .match - public typealias PropertyStub = Given - public typealias MethodStub = Given - public typealias SubscriptStub = Given + case (.m_addToDownloadQueue__tasks_tasks(let lhsTasks), .m_addToDownloadQueue__tasks_tasks(let rhsTasks)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTasks, rhs: rhsTasks, with: matcher), lhsTasks, rhsTasks, "tasks")) + return Matcher.ComparisonResult(results) - /// Convenience method - call setupMock() to extend debug information when failure occurs - public func setupMock(file: StaticString = #file, line: UInt = #line) { - self.file = file - self.line = line - } + case (.m_saveOfflineProgress__progress_progress(let lhsProgress), .m_saveOfflineProgress__progress_progress(let rhsProgress)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsProgress, rhs: rhsProgress, with: matcher), lhsProgress, rhsProgress, "progress")) + return Matcher.ComparisonResult(results) - /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals - public func resetMock(_ scopes: MockScope...) { - let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes - if scopes.contains(.invocation) { invocations = [] } - if scopes.contains(.given) { methodReturnValues = [] } - if scopes.contains(.perform) { methodPerformValues = [] } - } + case (.m_loadProgress__for_blockID(let lhsBlockid), .m_loadProgress__for_blockID(let rhsBlockid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockID")) + return Matcher.ComparisonResult(results) - public var currentDownloadTask: DownloadDataTask? { - get { invocations.append(.p_currentDownloadTask_get); return __p_currentDownloadTask ?? optionalGivenGetterValue(.p_currentDownloadTask_get, "DownloadManagerProtocolMock - stub value for currentDownloadTask was not defined") } - } - private var __p_currentDownloadTask: (DownloadDataTask)? + case (.m_loadAllOfflineProgress, .m_loadAllOfflineProgress): return .match + case (.m_deleteProgress__for_blockID(let lhsBlockid), .m_deleteProgress__for_blockID(let rhsBlockid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockID")) + return Matcher.ComparisonResult(results) + case (.m_deleteAllProgress, .m_deleteAllProgress): return .match + case (.m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(let lhsBlocks, let lhsDownloadquality), .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(let rhsBlocks, let rhsDownloadquality)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsDownloadquality, rhs: rhsDownloadquality, with: matcher), lhsDownloadquality, rhsDownloadquality, "downloadQuality")) + return Matcher.ComparisonResult(results) + case (.m_nextBlockForDownloading, .m_nextBlockForDownloading): return .match - open func publisher() -> AnyPublisher { - addInvocation(.m_publisher) - let perform = methodPerformValue(.m_publisher) as? () -> Void - perform?() - var __value: AnyPublisher - do { - __value = try methodReturnValue(.m_publisher).casted() - } catch { - onFatalFailure("Stub return value not specified for publisher(). Use given") - Failure("Stub return value not specified for publisher(). Use given") - } - return __value - } + case (.m_updateDownloadState__id_idstate_stateresumeData_resumeData(let lhsId, let lhsState, let lhsResumedata), .m_updateDownloadState__id_idstate_stateresumeData_resumeData(let rhsId, let rhsState, let rhsResumedata)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsId, rhs: rhsId, with: matcher), lhsId, rhsId, "id")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsState, rhs: rhsState, with: matcher), lhsState, rhsState, "state")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsResumedata, rhs: rhsResumedata, with: matcher), lhsResumedata, rhsResumedata, "resumeData")) + return Matcher.ComparisonResult(results) - open func eventPublisher() -> AnyPublisher { - addInvocation(.m_eventPublisher) - let perform = methodPerformValue(.m_eventPublisher) as? () -> Void - perform?() - var __value: AnyPublisher - do { - __value = try methodReturnValue(.m_eventPublisher).casted() - } catch { - onFatalFailure("Stub return value not specified for eventPublisher(). Use given") - Failure("Stub return value not specified for eventPublisher(). Use given") - } - return __value - } + case (.m_deleteDownloadDataTask__id_id(let lhsId), .m_deleteDownloadDataTask__id_id(let rhsId)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsId, rhs: rhsId, with: matcher), lhsId, rhsId, "id")) + return Matcher.ComparisonResult(results) - open func addToDownloadQueue(blocks: [CourseBlock]) throws { - addInvocation(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) - let perform = methodPerformValue(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void - perform?(`blocks`) - do { - _ = try methodReturnValue(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } - } + case (.m_saveDownloadDataTask__task(let lhsTask), .m_saveDownloadDataTask__task(let rhsTask)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTask, rhs: rhsTask, with: matcher), lhsTask, rhsTask, "_ task")) + return Matcher.ComparisonResult(results) - open func getDownloadTasks() -> [DownloadDataTask] { - addInvocation(.m_getDownloadTasks) - let perform = methodPerformValue(.m_getDownloadTasks) as? () -> Void - perform?() - var __value: [DownloadDataTask] - do { - __value = try methodReturnValue(.m_getDownloadTasks).casted() - } catch { - onFatalFailure("Stub return value not specified for getDownloadTasks(). Use given") - Failure("Stub return value not specified for getDownloadTasks(). Use given") - } - return __value + case (.m_downloadDataTask__for_blockId(let lhsBlockid), .m_downloadDataTask__for_blockId(let rhsBlockid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockId")) + return Matcher.ComparisonResult(results) + + case (.m_getDownloadDataTasks, .m_getDownloadDataTasks): return .match + + case (.m_getDownloadDataTasksForCourse__courseId(let lhsCourseid), .m_getDownloadDataTasksForCourse__courseId(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "_ courseId")) + return Matcher.ComparisonResult(results) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case let .m_set__userId_userId(p0): return p0.intValue + case .m_getUserID: return 0 + case .m_publisher: return 0 + case let .m_addToDownloadQueue__tasks_tasks(p0): return p0.intValue + case let .m_saveOfflineProgress__progress_progress(p0): return p0.intValue + case let .m_loadProgress__for_blockID(p0): return p0.intValue + case .m_loadAllOfflineProgress: return 0 + case let .m_deleteProgress__for_blockID(p0): return p0.intValue + case .m_deleteAllProgress: return 0 + case let .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(p0, p1): return p0.intValue + p1.intValue + case .m_nextBlockForDownloading: return 0 + case let .m_updateDownloadState__id_idstate_stateresumeData_resumeData(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case let .m_deleteDownloadDataTask__id_id(p0): return p0.intValue + case let .m_saveDownloadDataTask__task(p0): return p0.intValue + case let .m_downloadDataTask__for_blockId(p0): return p0.intValue + case .m_getDownloadDataTasks: return 0 + case let .m_getDownloadDataTasksForCourse__courseId(p0): return p0.intValue + } + } + func assertionName() -> String { + switch self { + case .m_set__userId_userId: return ".set(userId:)" + case .m_getUserID: return ".getUserID()" + case .m_publisher: return ".publisher()" + case .m_addToDownloadQueue__tasks_tasks: return ".addToDownloadQueue(tasks:)" + case .m_saveOfflineProgress__progress_progress: return ".saveOfflineProgress(progress:)" + case .m_loadProgress__for_blockID: return ".loadProgress(for:)" + case .m_loadAllOfflineProgress: return ".loadAllOfflineProgress()" + case .m_deleteProgress__for_blockID: return ".deleteProgress(for:)" + case .m_deleteAllProgress: return ".deleteAllProgress()" + case .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality: return ".addToDownloadQueue(blocks:downloadQuality:)" + case .m_nextBlockForDownloading: return ".nextBlockForDownloading()" + case .m_updateDownloadState__id_idstate_stateresumeData_resumeData: return ".updateDownloadState(id:state:resumeData:)" + case .m_deleteDownloadDataTask__id_id: return ".deleteDownloadDataTask(id:)" + case .m_saveDownloadDataTask__task: return ".saveDownloadDataTask(_:)" + case .m_downloadDataTask__for_blockId: return ".downloadDataTask(for:)" + case .m_getDownloadDataTasks: return ".getDownloadDataTasks()" + case .m_getDownloadDataTasksForCourse__courseId: return ".getDownloadDataTasksForCourse(_:)" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func getUserID(willReturn: Int?...) -> MethodStub { + return Given(method: .m_getUserID, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func publisher(willReturn: AnyPublisher...) -> MethodStub { + return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func loadProgress(for blockID: Parameter, willReturn: OfflineProgress?...) -> MethodStub { + return Given(method: .m_loadProgress__for_blockID(`blockID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func loadAllOfflineProgress(willReturn: [OfflineProgress]...) -> MethodStub { + return Given(method: .m_loadAllOfflineProgress, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func nextBlockForDownloading(willReturn: DownloadDataTask?...) -> MethodStub { + return Given(method: .m_nextBlockForDownloading, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func downloadDataTask(for blockId: Parameter, willReturn: DownloadDataTask?...) -> MethodStub { + return Given(method: .m_downloadDataTask__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getDownloadDataTasks(willReturn: [DownloadDataTask]...) -> MethodStub { + return Given(method: .m_getDownloadDataTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getDownloadDataTasksForCourse(_ courseId: Parameter, willReturn: [DownloadDataTask]...) -> MethodStub { + return Given(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getUserID(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Int?] = [] + let given: Given = { return Given(method: .m_getUserID, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Int?).self) + willProduce(stubber) + return given + } + public static func publisher(willProduce: (Stubber>) -> Void) -> MethodStub { + let willReturn: [AnyPublisher] = [] + let given: Given = { return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (AnyPublisher).self) + willProduce(stubber) + return given + } + public static func loadProgress(for blockID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [OfflineProgress?] = [] + let given: Given = { return Given(method: .m_loadProgress__for_blockID(`blockID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (OfflineProgress?).self) + willProduce(stubber) + return given + } + public static func loadAllOfflineProgress(willProduce: (Stubber<[OfflineProgress]>) -> Void) -> MethodStub { + let willReturn: [[OfflineProgress]] = [] + let given: Given = { return Given(method: .m_loadAllOfflineProgress, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([OfflineProgress]).self) + willProduce(stubber) + return given + } + public static func nextBlockForDownloading(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [DownloadDataTask?] = [] + let given: Given = { return Given(method: .m_nextBlockForDownloading, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (DownloadDataTask?).self) + willProduce(stubber) + return given + } + public static func downloadDataTask(for blockId: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [DownloadDataTask?] = [] + let given: Given = { return Given(method: .m_downloadDataTask__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (DownloadDataTask?).self) + willProduce(stubber) + return given + } + public static func getDownloadDataTasks(willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { + let willReturn: [[DownloadDataTask]] = [] + let given: Given = { return Given(method: .m_getDownloadDataTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([DownloadDataTask]).self) + willProduce(stubber) + return given + } + public static func getDownloadDataTasksForCourse(_ courseId: Parameter, willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { + let willReturn: [[DownloadDataTask]] = [] + let given: Given = { return Given(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([DownloadDataTask]).self) + willProduce(stubber) + return given + } + public static func deleteDownloadDataTask(id: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_deleteDownloadDataTask__id_id(`id`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func deleteDownloadDataTask(id: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_deleteDownloadDataTask__id_id(`id`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func set(userId: Parameter) -> Verify { return Verify(method: .m_set__userId_userId(`userId`))} + public static func getUserID() -> Verify { return Verify(method: .m_getUserID)} + public static func publisher() -> Verify { return Verify(method: .m_publisher)} + public static func addToDownloadQueue(tasks: Parameter<[DownloadDataTask]>) -> Verify { return Verify(method: .m_addToDownloadQueue__tasks_tasks(`tasks`))} + public static func saveOfflineProgress(progress: Parameter) -> Verify { return Verify(method: .m_saveOfflineProgress__progress_progress(`progress`))} + public static func loadProgress(for blockID: Parameter) -> Verify { return Verify(method: .m_loadProgress__for_blockID(`blockID`))} + public static func loadAllOfflineProgress() -> Verify { return Verify(method: .m_loadAllOfflineProgress)} + public static func deleteProgress(for blockID: Parameter) -> Verify { return Verify(method: .m_deleteProgress__for_blockID(`blockID`))} + public static func deleteAllProgress() -> Verify { return Verify(method: .m_deleteAllProgress)} + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, downloadQuality: Parameter) -> Verify { return Verify(method: .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(`blocks`, `downloadQuality`))} + public static func nextBlockForDownloading() -> Verify { return Verify(method: .m_nextBlockForDownloading)} + public static func updateDownloadState(id: Parameter, state: Parameter, resumeData: Parameter) -> Verify { return Verify(method: .m_updateDownloadState__id_idstate_stateresumeData_resumeData(`id`, `state`, `resumeData`))} + public static func deleteDownloadDataTask(id: Parameter) -> Verify { return Verify(method: .m_deleteDownloadDataTask__id_id(`id`))} + public static func saveDownloadDataTask(_ task: Parameter) -> Verify { return Verify(method: .m_saveDownloadDataTask__task(`task`))} + public static func downloadDataTask(for blockId: Parameter) -> Verify { return Verify(method: .m_downloadDataTask__for_blockId(`blockId`))} + public static func getDownloadDataTasks() -> Verify { return Verify(method: .m_getDownloadDataTasks)} + public static func getDownloadDataTasksForCourse(_ courseId: Parameter) -> Verify { return Verify(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`))} + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func set(userId: Parameter, perform: @escaping (Int) -> Void) -> Perform { + return Perform(method: .m_set__userId_userId(`userId`), performs: perform) + } + public static func getUserID(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getUserID, performs: perform) + } + public static func publisher(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_publisher, performs: perform) + } + public static func addToDownloadQueue(tasks: Parameter<[DownloadDataTask]>, perform: @escaping ([DownloadDataTask]) -> Void) -> Perform { + return Perform(method: .m_addToDownloadQueue__tasks_tasks(`tasks`), performs: perform) + } + public static func saveOfflineProgress(progress: Parameter, perform: @escaping (OfflineProgress) -> Void) -> Perform { + return Perform(method: .m_saveOfflineProgress__progress_progress(`progress`), performs: perform) + } + public static func loadProgress(for blockID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_loadProgress__for_blockID(`blockID`), performs: perform) + } + public static func loadAllOfflineProgress(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_loadAllOfflineProgress, performs: perform) + } + public static func deleteProgress(for blockID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_deleteProgress__for_blockID(`blockID`), performs: perform) + } + public static func deleteAllProgress(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_deleteAllProgress, performs: perform) + } + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, downloadQuality: Parameter, perform: @escaping ([CourseBlock], DownloadQuality) -> Void) -> Perform { + return Perform(method: .m_addToDownloadQueue__blocks_blocksdownloadQuality_downloadQuality(`blocks`, `downloadQuality`), performs: perform) + } + public static func nextBlockForDownloading(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_nextBlockForDownloading, performs: perform) + } + public static func updateDownloadState(id: Parameter, state: Parameter, resumeData: Parameter, perform: @escaping (String, DownloadState, Data?) -> Void) -> Perform { + return Perform(method: .m_updateDownloadState__id_idstate_stateresumeData_resumeData(`id`, `state`, `resumeData`), performs: perform) + } + public static func deleteDownloadDataTask(id: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_deleteDownloadDataTask__id_id(`id`), performs: perform) + } + public static func saveDownloadDataTask(_ task: Parameter, perform: @escaping (DownloadDataTask) -> Void) -> Perform { + return Perform(method: .m_saveDownloadDataTask__task(`task`), performs: perform) + } + public static func downloadDataTask(for blockId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_downloadDataTask__for_blockId(`blockId`), performs: perform) + } + public static func getDownloadDataTasks(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getDownloadDataTasks, performs: perform) + } + public static func getDownloadDataTasksForCourse(_ courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getDownloadDataTasksForCourse__courseId(`courseId`), performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - CoreStorage + +open class CoreStorageMock: CoreStorage, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var accessToken: String? { + get { invocations.append(.p_accessToken_get); return __p_accessToken ?? optionalGivenGetterValue(.p_accessToken_get, "CoreStorageMock - stub value for accessToken was not defined") } + set { invocations.append(.p_accessToken_set(.value(newValue))); __p_accessToken = newValue } + } + private var __p_accessToken: (String)? + + public var refreshToken: String? { + get { invocations.append(.p_refreshToken_get); return __p_refreshToken ?? optionalGivenGetterValue(.p_refreshToken_get, "CoreStorageMock - stub value for refreshToken was not defined") } + set { invocations.append(.p_refreshToken_set(.value(newValue))); __p_refreshToken = newValue } + } + private var __p_refreshToken: (String)? + + public var pushToken: String? { + get { invocations.append(.p_pushToken_get); return __p_pushToken ?? optionalGivenGetterValue(.p_pushToken_get, "CoreStorageMock - stub value for pushToken was not defined") } + set { invocations.append(.p_pushToken_set(.value(newValue))); __p_pushToken = newValue } + } + private var __p_pushToken: (String)? + + public var appleSignFullName: String? { + get { invocations.append(.p_appleSignFullName_get); return __p_appleSignFullName ?? optionalGivenGetterValue(.p_appleSignFullName_get, "CoreStorageMock - stub value for appleSignFullName was not defined") } + set { invocations.append(.p_appleSignFullName_set(.value(newValue))); __p_appleSignFullName = newValue } + } + private var __p_appleSignFullName: (String)? + + public var appleSignEmail: String? { + get { invocations.append(.p_appleSignEmail_get); return __p_appleSignEmail ?? optionalGivenGetterValue(.p_appleSignEmail_get, "CoreStorageMock - stub value for appleSignEmail was not defined") } + set { invocations.append(.p_appleSignEmail_set(.value(newValue))); __p_appleSignEmail = newValue } + } + private var __p_appleSignEmail: (String)? + + public var cookiesDate: Date? { + get { invocations.append(.p_cookiesDate_get); return __p_cookiesDate ?? optionalGivenGetterValue(.p_cookiesDate_get, "CoreStorageMock - stub value for cookiesDate was not defined") } + set { invocations.append(.p_cookiesDate_set(.value(newValue))); __p_cookiesDate = newValue } + } + private var __p_cookiesDate: (Date)? + + public var reviewLastShownVersion: String? { + get { invocations.append(.p_reviewLastShownVersion_get); return __p_reviewLastShownVersion ?? optionalGivenGetterValue(.p_reviewLastShownVersion_get, "CoreStorageMock - stub value for reviewLastShownVersion was not defined") } + set { invocations.append(.p_reviewLastShownVersion_set(.value(newValue))); __p_reviewLastShownVersion = newValue } + } + private var __p_reviewLastShownVersion: (String)? + + public var lastReviewDate: Date? { + get { invocations.append(.p_lastReviewDate_get); return __p_lastReviewDate ?? optionalGivenGetterValue(.p_lastReviewDate_get, "CoreStorageMock - stub value for lastReviewDate was not defined") } + set { invocations.append(.p_lastReviewDate_set(.value(newValue))); __p_lastReviewDate = newValue } + } + private var __p_lastReviewDate: (Date)? + + public var user: DataLayer.User? { + get { invocations.append(.p_user_get); return __p_user ?? optionalGivenGetterValue(.p_user_get, "CoreStorageMock - stub value for user was not defined") } + set { invocations.append(.p_user_set(.value(newValue))); __p_user = newValue } + } + private var __p_user: (DataLayer.User)? + + public var userSettings: UserSettings? { + get { invocations.append(.p_userSettings_get); return __p_userSettings ?? optionalGivenGetterValue(.p_userSettings_get, "CoreStorageMock - stub value for userSettings was not defined") } + set { invocations.append(.p_userSettings_set(.value(newValue))); __p_userSettings = newValue } + } + private var __p_userSettings: (UserSettings)? + + public var resetAppSupportDirectoryUserData: Bool? { + get { invocations.append(.p_resetAppSupportDirectoryUserData_get); return __p_resetAppSupportDirectoryUserData ?? optionalGivenGetterValue(.p_resetAppSupportDirectoryUserData_get, "CoreStorageMock - stub value for resetAppSupportDirectoryUserData was not defined") } + set { invocations.append(.p_resetAppSupportDirectoryUserData_set(.value(newValue))); __p_resetAppSupportDirectoryUserData = newValue } + } + private var __p_resetAppSupportDirectoryUserData: (Bool)? + + public var useRelativeDates: Bool { + get { invocations.append(.p_useRelativeDates_get); return __p_useRelativeDates ?? givenGetterValue(.p_useRelativeDates_get, "CoreStorageMock - stub value for useRelativeDates was not defined") } + set { invocations.append(.p_useRelativeDates_set(.value(newValue))); __p_useRelativeDates = newValue } + } + private var __p_useRelativeDates: (Bool)? + + + + + + open func clear() { + addInvocation(.m_clear) + let perform = methodPerformValue(.m_clear) as? () -> Void + perform?() + } + + + fileprivate enum MethodType { + case m_clear + case p_accessToken_get + case p_accessToken_set(Parameter) + case p_refreshToken_get + case p_refreshToken_set(Parameter) + case p_pushToken_get + case p_pushToken_set(Parameter) + case p_appleSignFullName_get + case p_appleSignFullName_set(Parameter) + case p_appleSignEmail_get + case p_appleSignEmail_set(Parameter) + case p_cookiesDate_get + case p_cookiesDate_set(Parameter) + case p_reviewLastShownVersion_get + case p_reviewLastShownVersion_set(Parameter) + case p_lastReviewDate_get + case p_lastReviewDate_set(Parameter) + case p_user_get + case p_user_set(Parameter) + case p_userSettings_get + case p_userSettings_set(Parameter) + case p_resetAppSupportDirectoryUserData_get + case p_resetAppSupportDirectoryUserData_set(Parameter) + case p_useRelativeDates_get + case p_useRelativeDates_set(Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_clear, .m_clear): return .match + case (.p_accessToken_get,.p_accessToken_get): return Matcher.ComparisonResult.match + case (.p_accessToken_set(let left),.p_accessToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_refreshToken_get,.p_refreshToken_get): return Matcher.ComparisonResult.match + case (.p_refreshToken_set(let left),.p_refreshToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_pushToken_get,.p_pushToken_get): return Matcher.ComparisonResult.match + case (.p_pushToken_set(let left),.p_pushToken_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_appleSignFullName_get,.p_appleSignFullName_get): return Matcher.ComparisonResult.match + case (.p_appleSignFullName_set(let left),.p_appleSignFullName_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_appleSignEmail_get,.p_appleSignEmail_get): return Matcher.ComparisonResult.match + case (.p_appleSignEmail_set(let left),.p_appleSignEmail_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_cookiesDate_get,.p_cookiesDate_get): return Matcher.ComparisonResult.match + case (.p_cookiesDate_set(let left),.p_cookiesDate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_reviewLastShownVersion_get,.p_reviewLastShownVersion_get): return Matcher.ComparisonResult.match + case (.p_reviewLastShownVersion_set(let left),.p_reviewLastShownVersion_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_lastReviewDate_get,.p_lastReviewDate_get): return Matcher.ComparisonResult.match + case (.p_lastReviewDate_set(let left),.p_lastReviewDate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_user_get,.p_user_get): return Matcher.ComparisonResult.match + case (.p_user_set(let left),.p_user_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_userSettings_get,.p_userSettings_get): return Matcher.ComparisonResult.match + case (.p_userSettings_set(let left),.p_userSettings_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_resetAppSupportDirectoryUserData_get,.p_resetAppSupportDirectoryUserData_get): return Matcher.ComparisonResult.match + case (.p_resetAppSupportDirectoryUserData_set(let left),.p_resetAppSupportDirectoryUserData_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_useRelativeDates_get,.p_useRelativeDates_get): return Matcher.ComparisonResult.match + case (.p_useRelativeDates_set(let left),.p_useRelativeDates_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_clear: return 0 + case .p_accessToken_get: return 0 + case .p_accessToken_set(let newValue): return newValue.intValue + case .p_refreshToken_get: return 0 + case .p_refreshToken_set(let newValue): return newValue.intValue + case .p_pushToken_get: return 0 + case .p_pushToken_set(let newValue): return newValue.intValue + case .p_appleSignFullName_get: return 0 + case .p_appleSignFullName_set(let newValue): return newValue.intValue + case .p_appleSignEmail_get: return 0 + case .p_appleSignEmail_set(let newValue): return newValue.intValue + case .p_cookiesDate_get: return 0 + case .p_cookiesDate_set(let newValue): return newValue.intValue + case .p_reviewLastShownVersion_get: return 0 + case .p_reviewLastShownVersion_set(let newValue): return newValue.intValue + case .p_lastReviewDate_get: return 0 + case .p_lastReviewDate_set(let newValue): return newValue.intValue + case .p_user_get: return 0 + case .p_user_set(let newValue): return newValue.intValue + case .p_userSettings_get: return 0 + case .p_userSettings_set(let newValue): return newValue.intValue + case .p_resetAppSupportDirectoryUserData_get: return 0 + case .p_resetAppSupportDirectoryUserData_set(let newValue): return newValue.intValue + case .p_useRelativeDates_get: return 0 + case .p_useRelativeDates_set(let newValue): return newValue.intValue + } + } + func assertionName() -> String { + switch self { + case .m_clear: return ".clear()" + case .p_accessToken_get: return "[get] .accessToken" + case .p_accessToken_set: return "[set] .accessToken" + case .p_refreshToken_get: return "[get] .refreshToken" + case .p_refreshToken_set: return "[set] .refreshToken" + case .p_pushToken_get: return "[get] .pushToken" + case .p_pushToken_set: return "[set] .pushToken" + case .p_appleSignFullName_get: return "[get] .appleSignFullName" + case .p_appleSignFullName_set: return "[set] .appleSignFullName" + case .p_appleSignEmail_get: return "[get] .appleSignEmail" + case .p_appleSignEmail_set: return "[set] .appleSignEmail" + case .p_cookiesDate_get: return "[get] .cookiesDate" + case .p_cookiesDate_set: return "[set] .cookiesDate" + case .p_reviewLastShownVersion_get: return "[get] .reviewLastShownVersion" + case .p_reviewLastShownVersion_set: return "[set] .reviewLastShownVersion" + case .p_lastReviewDate_get: return "[get] .lastReviewDate" + case .p_lastReviewDate_set: return "[set] .lastReviewDate" + case .p_user_get: return "[get] .user" + case .p_user_set: return "[set] .user" + case .p_userSettings_get: return "[get] .userSettings" + case .p_userSettings_set: return "[set] .userSettings" + case .p_resetAppSupportDirectoryUserData_get: return "[get] .resetAppSupportDirectoryUserData" + case .p_resetAppSupportDirectoryUserData_set: return "[set] .resetAppSupportDirectoryUserData" + case .p_useRelativeDates_get: return "[get] .useRelativeDates" + case .p_useRelativeDates_set: return "[set] .useRelativeDates" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func accessToken(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_accessToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func refreshToken(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_refreshToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func pushToken(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_pushToken_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignFullName(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_appleSignFullName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func appleSignEmail(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_appleSignEmail_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func cookiesDate(getter defaultValue: Date?...) -> PropertyStub { + return Given(method: .p_cookiesDate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func reviewLastShownVersion(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_reviewLastShownVersion_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func lastReviewDate(getter defaultValue: Date?...) -> PropertyStub { + return Given(method: .p_lastReviewDate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func user(getter defaultValue: DataLayer.User?...) -> PropertyStub { + return Given(method: .p_user_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func userSettings(getter defaultValue: UserSettings?...) -> PropertyStub { + return Given(method: .p_userSettings_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func resetAppSupportDirectoryUserData(getter defaultValue: Bool?...) -> PropertyStub { + return Given(method: .p_resetAppSupportDirectoryUserData_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func useRelativeDates(getter defaultValue: Bool...) -> PropertyStub { + return Given(method: .p_useRelativeDates_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static func clear() -> Verify { return Verify(method: .m_clear)} + public static var accessToken: Verify { return Verify(method: .p_accessToken_get) } + public static func accessToken(set newValue: Parameter) -> Verify { return Verify(method: .p_accessToken_set(newValue)) } + public static var refreshToken: Verify { return Verify(method: .p_refreshToken_get) } + public static func refreshToken(set newValue: Parameter) -> Verify { return Verify(method: .p_refreshToken_set(newValue)) } + public static var pushToken: Verify { return Verify(method: .p_pushToken_get) } + public static func pushToken(set newValue: Parameter) -> Verify { return Verify(method: .p_pushToken_set(newValue)) } + public static var appleSignFullName: Verify { return Verify(method: .p_appleSignFullName_get) } + public static func appleSignFullName(set newValue: Parameter) -> Verify { return Verify(method: .p_appleSignFullName_set(newValue)) } + public static var appleSignEmail: Verify { return Verify(method: .p_appleSignEmail_get) } + public static func appleSignEmail(set newValue: Parameter) -> Verify { return Verify(method: .p_appleSignEmail_set(newValue)) } + public static var cookiesDate: Verify { return Verify(method: .p_cookiesDate_get) } + public static func cookiesDate(set newValue: Parameter) -> Verify { return Verify(method: .p_cookiesDate_set(newValue)) } + public static var reviewLastShownVersion: Verify { return Verify(method: .p_reviewLastShownVersion_get) } + public static func reviewLastShownVersion(set newValue: Parameter) -> Verify { return Verify(method: .p_reviewLastShownVersion_set(newValue)) } + public static var lastReviewDate: Verify { return Verify(method: .p_lastReviewDate_get) } + public static func lastReviewDate(set newValue: Parameter) -> Verify { return Verify(method: .p_lastReviewDate_set(newValue)) } + public static var user: Verify { return Verify(method: .p_user_get) } + public static func user(set newValue: Parameter) -> Verify { return Verify(method: .p_user_set(newValue)) } + public static var userSettings: Verify { return Verify(method: .p_userSettings_get) } + public static func userSettings(set newValue: Parameter) -> Verify { return Verify(method: .p_userSettings_set(newValue)) } + public static var resetAppSupportDirectoryUserData: Verify { return Verify(method: .p_resetAppSupportDirectoryUserData_get) } + public static func resetAppSupportDirectoryUserData(set newValue: Parameter) -> Verify { return Verify(method: .p_resetAppSupportDirectoryUserData_set(newValue)) } + public static var useRelativeDates: Verify { return Verify(method: .p_useRelativeDates_get) } + public static func useRelativeDates(set newValue: Parameter) -> Verify { return Verify(method: .p_useRelativeDates_set(newValue)) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + public static func clear(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_clear, performs: perform) + } + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + +// MARK: - DownloadManagerProtocol + +open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var currentDownloadTask: DownloadDataTask? { + get { invocations.append(.p_currentDownloadTask_get); return __p_currentDownloadTask ?? optionalGivenGetterValue(.p_currentDownloadTask_get, "DownloadManagerProtocolMock - stub value for currentDownloadTask was not defined") } + } + private var __p_currentDownloadTask: (DownloadDataTask)? + + + + + + open func publisher() -> AnyPublisher { + addInvocation(.m_publisher) + let perform = methodPerformValue(.m_publisher) as? () -> Void + perform?() + var __value: AnyPublisher + do { + __value = try methodReturnValue(.m_publisher).casted() + } catch { + onFatalFailure("Stub return value not specified for publisher(). Use given") + Failure("Stub return value not specified for publisher(). Use given") + } + return __value + } + + open func eventPublisher() -> AnyPublisher { + addInvocation(.m_eventPublisher) + let perform = methodPerformValue(.m_eventPublisher) as? () -> Void + perform?() + var __value: AnyPublisher + do { + __value = try methodReturnValue(.m_eventPublisher).casted() + } catch { + onFatalFailure("Stub return value not specified for eventPublisher(). Use given") + Failure("Stub return value not specified for eventPublisher(). Use given") + } + return __value + } + + open func addToDownloadQueue(blocks: [CourseBlock]) throws { + addInvocation(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) + let perform = methodPerformValue(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void + perform?(`blocks`) + do { + _ = try methodReturnValue(.m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func getDownloadTasks() -> [DownloadDataTask] { + addInvocation(.m_getDownloadTasks) + let perform = methodPerformValue(.m_getDownloadTasks) as? () -> Void + perform?() + var __value: [DownloadDataTask] + do { + __value = try methodReturnValue(.m_getDownloadTasks).casted() + } catch { + onFatalFailure("Stub return value not specified for getDownloadTasks(). Use given") + Failure("Stub return value not specified for getDownloadTasks(). Use given") + } + return __value + } + + open func getDownloadTasksForCourse(_ courseId: String) -> [DownloadDataTask] { + addInvocation(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))) + let perform = methodPerformValue(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))) as? (String) -> Void + perform?(`courseId`) + var __value: [DownloadDataTask] + do { + __value = try methodReturnValue(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))).casted() + } catch { + onFatalFailure("Stub return value not specified for getDownloadTasksForCourse(_ courseId: String). Use given") + Failure("Stub return value not specified for getDownloadTasksForCourse(_ courseId: String). Use given") + } + return __value + } + + open func cancelDownloading(courseId: String, blocks: [CourseBlock]) throws { + addInvocation(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))) + let perform = methodPerformValue(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))) as? (String, [CourseBlock]) -> Void + perform?(`courseId`, `blocks`) + do { + _ = try methodReturnValue(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func cancelDownloading(task: DownloadDataTask) throws { + addInvocation(.m_cancelDownloading__task_task(Parameter.value(`task`))) + let perform = methodPerformValue(.m_cancelDownloading__task_task(Parameter.value(`task`))) as? (DownloadDataTask) -> Void + perform?(`task`) + do { + _ = try methodReturnValue(.m_cancelDownloading__task_task(Parameter.value(`task`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func cancelDownloading(courseId: String) throws { + addInvocation(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))) + let perform = methodPerformValue(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))) as? (String) -> Void + perform?(`courseId`) + do { + _ = try methodReturnValue(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func cancelAllDownloading() throws { + addInvocation(.m_cancelAllDownloading) + let perform = methodPerformValue(.m_cancelAllDownloading) as? () -> Void + perform?() + do { + _ = try methodReturnValue(.m_cancelAllDownloading).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func deleteFile(blocks: [CourseBlock]) { + addInvocation(.m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) + let perform = methodPerformValue(.m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void + perform?(`blocks`) + } + + open func deleteAllFiles() { + addInvocation(.m_deleteAllFiles) + let perform = methodPerformValue(.m_deleteAllFiles) as? () -> Void + perform?() + } + + open func fileUrl(for blockId: String) -> URL? { + addInvocation(.m_fileUrl__for_blockId(Parameter.value(`blockId`))) + let perform = methodPerformValue(.m_fileUrl__for_blockId(Parameter.value(`blockId`))) as? (String) -> Void + perform?(`blockId`) + var __value: URL? = nil + do { + __value = try methodReturnValue(.m_fileUrl__for_blockId(Parameter.value(`blockId`))).casted() + } catch { + // do nothing + } + return __value + } + + open func updateUnzippedFileSize(for sequentials: [CourseSequential]) -> [CourseSequential] { + addInvocation(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))) + let perform = methodPerformValue(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))) as? ([CourseSequential]) -> Void + perform?(`sequentials`) + var __value: [CourseSequential] + do { + __value = try methodReturnValue(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))).casted() + } catch { + onFatalFailure("Stub return value not specified for updateUnzippedFileSize(for sequentials: [CourseSequential]). Use given") + Failure("Stub return value not specified for updateUnzippedFileSize(for sequentials: [CourseSequential]). Use given") + } + return __value + } + + open func resumeDownloading() throws { + addInvocation(.m_resumeDownloading) + let perform = methodPerformValue(.m_resumeDownloading) as? () -> Void + perform?() + do { + _ = try methodReturnValue(.m_resumeDownloading).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } + } + + open func isLargeVideosSize(blocks: [CourseBlock]) -> Bool { + addInvocation(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) + let perform = methodPerformValue(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void + perform?(`blocks`) + var __value: Bool + do { + __value = try methodReturnValue(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))).casted() + } catch { + onFatalFailure("Stub return value not specified for isLargeVideosSize(blocks: [CourseBlock]). Use given") + Failure("Stub return value not specified for isLargeVideosSize(blocks: [CourseBlock]). Use given") + } + return __value + } + + open func removeAppSupportDirectoryUnusedContent() { + addInvocation(.m_removeAppSupportDirectoryUnusedContent) + let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void + perform?() + } + + + fileprivate enum MethodType { + case m_publisher + case m_eventPublisher + case m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>) + case m_getDownloadTasks + case m_getDownloadTasksForCourse__courseId(Parameter) + case m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter, Parameter<[CourseBlock]>) + case m_cancelDownloading__task_task(Parameter) + case m_cancelDownloading__courseId_courseId(Parameter) + case m_cancelAllDownloading + case m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>) + case m_deleteAllFiles + case m_fileUrl__for_blockId(Parameter) + case m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>) + case m_resumeDownloading + case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) + case m_removeAppSupportDirectoryUnusedContent + case p_currentDownloadTask_get + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_publisher, .m_publisher): return .match + + case (.m_eventPublisher, .m_eventPublisher): return .match + + case (.m_addToDownloadQueue__blocks_blocks(let lhsBlocks), .m_addToDownloadQueue__blocks_blocks(let rhsBlocks)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + return Matcher.ComparisonResult(results) + + case (.m_getDownloadTasks, .m_getDownloadTasks): return .match + + case (.m_getDownloadTasksForCourse__courseId(let lhsCourseid), .m_getDownloadTasksForCourse__courseId(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "_ courseId")) + return Matcher.ComparisonResult(results) + + case (.m_cancelDownloading__courseId_courseIdblocks_blocks(let lhsCourseid, let lhsBlocks), .m_cancelDownloading__courseId_courseIdblocks_blocks(let rhsCourseid, let rhsBlocks)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseId")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + return Matcher.ComparisonResult(results) + + case (.m_cancelDownloading__task_task(let lhsTask), .m_cancelDownloading__task_task(let rhsTask)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTask, rhs: rhsTask, with: matcher), lhsTask, rhsTask, "task")) + return Matcher.ComparisonResult(results) + + case (.m_cancelDownloading__courseId_courseId(let lhsCourseid), .m_cancelDownloading__courseId_courseId(let rhsCourseid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseId")) + return Matcher.ComparisonResult(results) + + case (.m_cancelAllDownloading, .m_cancelAllDownloading): return .match + + case (.m_deleteFile__blocks_blocks(let lhsBlocks), .m_deleteFile__blocks_blocks(let rhsBlocks)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + return Matcher.ComparisonResult(results) + + case (.m_deleteAllFiles, .m_deleteAllFiles): return .match + + case (.m_fileUrl__for_blockId(let lhsBlockid), .m_fileUrl__for_blockId(let rhsBlockid)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockId")) + return Matcher.ComparisonResult(results) + + case (.m_updateUnzippedFileSize__for_sequentials(let lhsSequentials), .m_updateUnzippedFileSize__for_sequentials(let rhsSequentials)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSequentials, rhs: rhsSequentials, with: matcher), lhsSequentials, rhsSequentials, "for sequentials")) + return Matcher.ComparisonResult(results) + + case (.m_resumeDownloading, .m_resumeDownloading): return .match + + case (.m_isLargeVideosSize__blocks_blocks(let lhsBlocks), .m_isLargeVideosSize__blocks_blocks(let rhsBlocks)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + return Matcher.ComparisonResult(results) + + case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match + case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .m_publisher: return 0 + case .m_eventPublisher: return 0 + case let .m_addToDownloadQueue__blocks_blocks(p0): return p0.intValue + case .m_getDownloadTasks: return 0 + case let .m_getDownloadTasksForCourse__courseId(p0): return p0.intValue + case let .m_cancelDownloading__courseId_courseIdblocks_blocks(p0, p1): return p0.intValue + p1.intValue + case let .m_cancelDownloading__task_task(p0): return p0.intValue + case let .m_cancelDownloading__courseId_courseId(p0): return p0.intValue + case .m_cancelAllDownloading: return 0 + case let .m_deleteFile__blocks_blocks(p0): return p0.intValue + case .m_deleteAllFiles: return 0 + case let .m_fileUrl__for_blockId(p0): return p0.intValue + case let .m_updateUnzippedFileSize__for_sequentials(p0): return p0.intValue + case .m_resumeDownloading: return 0 + case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue + case .m_removeAppSupportDirectoryUnusedContent: return 0 + case .p_currentDownloadTask_get: return 0 + } + } + func assertionName() -> String { + switch self { + case .m_publisher: return ".publisher()" + case .m_eventPublisher: return ".eventPublisher()" + case .m_addToDownloadQueue__blocks_blocks: return ".addToDownloadQueue(blocks:)" + case .m_getDownloadTasks: return ".getDownloadTasks()" + case .m_getDownloadTasksForCourse__courseId: return ".getDownloadTasksForCourse(_:)" + case .m_cancelDownloading__courseId_courseIdblocks_blocks: return ".cancelDownloading(courseId:blocks:)" + case .m_cancelDownloading__task_task: return ".cancelDownloading(task:)" + case .m_cancelDownloading__courseId_courseId: return ".cancelDownloading(courseId:)" + case .m_cancelAllDownloading: return ".cancelAllDownloading()" + case .m_deleteFile__blocks_blocks: return ".deleteFile(blocks:)" + case .m_deleteAllFiles: return ".deleteAllFiles()" + case .m_fileUrl__for_blockId: return ".fileUrl(for:)" + case .m_updateUnzippedFileSize__for_sequentials: return ".updateUnzippedFileSize(for:)" + case .m_resumeDownloading: return ".resumeDownloading()" + case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" + case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" + case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func currentDownloadTask(getter defaultValue: DownloadDataTask?...) -> PropertyStub { + return Given(method: .p_currentDownloadTask_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + public static func publisher(willReturn: AnyPublisher...) -> MethodStub { + return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func eventPublisher(willReturn: AnyPublisher...) -> MethodStub { + return Given(method: .m_eventPublisher, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getDownloadTasks(willReturn: [DownloadDataTask]...) -> MethodStub { + return Given(method: .m_getDownloadTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getDownloadTasksForCourse(_ courseId: Parameter, willReturn: [DownloadDataTask]...) -> MethodStub { + return Given(method: .m_getDownloadTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func fileUrl(for blockId: Parameter, willReturn: URL?...) -> MethodStub { + return Given(method: .m_fileUrl__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, willReturn: [CourseSequential]...) -> MethodStub { + return Given(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, willReturn: Bool...) -> MethodStub { + return Given(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func publisher(willProduce: (Stubber>) -> Void) -> MethodStub { + let willReturn: [AnyPublisher] = [] + let given: Given = { return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (AnyPublisher).self) + willProduce(stubber) + return given + } + public static func eventPublisher(willProduce: (Stubber>) -> Void) -> MethodStub { + let willReturn: [AnyPublisher] = [] + let given: Given = { return Given(method: .m_eventPublisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (AnyPublisher).self) + willProduce(stubber) + return given + } + public static func getDownloadTasks(willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { + let willReturn: [[DownloadDataTask]] = [] + let given: Given = { return Given(method: .m_getDownloadTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([DownloadDataTask]).self) + willProduce(stubber) + return given + } + public static func getDownloadTasksForCourse(_ courseId: Parameter, willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { + let willReturn: [[DownloadDataTask]] = [] + let given: Given = { return Given(method: .m_getDownloadTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([DownloadDataTask]).self) + willProduce(stubber) + return given + } + public static func fileUrl(for blockId: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [URL?] = [] + let given: Given = { return Given(method: .m_fileUrl__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (URL?).self) + willProduce(stubber) + return given + } + public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, willProduce: (Stubber<[CourseSequential]>) -> Void) -> MethodStub { + let willReturn: [[CourseSequential]] = [] + let given: Given = { return Given(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseSequential]).self) + willProduce(stubber) + return given + } + public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [Bool] = [] + let given: Given = { return Given(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (Bool).self) + willProduce(stubber) + return given + } + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, willThrow: Error...) -> MethodStub { + return Given(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, willThrow: Error...) -> MethodStub { + return Given(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func cancelDownloading(task: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_cancelDownloading__task_task(`task`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func cancelDownloading(task: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_cancelDownloading__task_task(`task`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func cancelDownloading(courseId: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_cancelDownloading__courseId_courseId(`courseId`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func cancelDownloading(courseId: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_cancelDownloading__courseId_courseId(`courseId`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func cancelAllDownloading(willThrow: Error...) -> MethodStub { + return Given(method: .m_cancelAllDownloading, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func cancelAllDownloading(willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_cancelAllDownloading, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func resumeDownloading(willThrow: Error...) -> MethodStub { + return Given(method: .m_resumeDownloading, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func resumeDownloading(willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_resumeDownloading, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + } + + public struct Verify { + fileprivate var method: MethodType + + public static func publisher() -> Verify { return Verify(method: .m_publisher)} + public static func eventPublisher() -> Verify { return Verify(method: .m_eventPublisher)} + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_addToDownloadQueue__blocks_blocks(`blocks`))} + public static func getDownloadTasks() -> Verify { return Verify(method: .m_getDownloadTasks)} + public static func getDownloadTasksForCourse(_ courseId: Parameter) -> Verify { return Verify(method: .m_getDownloadTasksForCourse__courseId(`courseId`))} + public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`))} + public static func cancelDownloading(task: Parameter) -> Verify { return Verify(method: .m_cancelDownloading__task_task(`task`))} + public static func cancelDownloading(courseId: Parameter) -> Verify { return Verify(method: .m_cancelDownloading__courseId_courseId(`courseId`))} + public static func cancelAllDownloading() -> Verify { return Verify(method: .m_cancelAllDownloading)} + public static func deleteFile(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_deleteFile__blocks_blocks(`blocks`))} + public static func deleteAllFiles() -> Verify { return Verify(method: .m_deleteAllFiles)} + public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} + public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>) -> Verify { return Verify(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`))} + public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} + public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} + public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} + public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } } - open func getDownloadTasksForCourse(_ courseId: String) -> [DownloadDataTask] { - addInvocation(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))) - let perform = methodPerformValue(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))) as? (String) -> Void - perform?(`courseId`) - var __value: [DownloadDataTask] - do { - __value = try methodReturnValue(.m_getDownloadTasksForCourse__courseId(Parameter.value(`courseId`))).casted() - } catch { - onFatalFailure("Stub return value not specified for getDownloadTasksForCourse(_ courseId: String). Use given") - Failure("Stub return value not specified for getDownloadTasksForCourse(_ courseId: String). Use given") - } - return __value - } + public struct Perform { + fileprivate var method: MethodType + var performs: Any - open func cancelDownloading(courseId: String, blocks: [CourseBlock]) throws { - addInvocation(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))) - let perform = methodPerformValue(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))) as? (String, [CourseBlock]) -> Void - perform?(`courseId`, `blocks`) - do { - _ = try methodReturnValue(.m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter.value(`courseId`), Parameter<[CourseBlock]>.value(`blocks`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + public static func publisher(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_publisher, performs: perform) + } + public static func eventPublisher(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_eventPublisher, performs: perform) + } + public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { + return Perform(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), performs: perform) + } + public static func getDownloadTasks(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getDownloadTasks, performs: perform) + } + public static func getDownloadTasksForCourse(_ courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getDownloadTasksForCourse__courseId(`courseId`), performs: perform) + } + public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, perform: @escaping (String, [CourseBlock]) -> Void) -> Perform { + return Perform(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), performs: perform) + } + public static func cancelDownloading(task: Parameter, perform: @escaping (DownloadDataTask) -> Void) -> Perform { + return Perform(method: .m_cancelDownloading__task_task(`task`), performs: perform) + } + public static func cancelDownloading(courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_cancelDownloading__courseId_courseId(`courseId`), performs: perform) + } + public static func cancelAllDownloading(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_cancelAllDownloading, performs: perform) + } + public static func deleteFile(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { + return Perform(method: .m_deleteFile__blocks_blocks(`blocks`), performs: perform) + } + public static func deleteAllFiles(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_deleteAllFiles, performs: perform) + } + public static func fileUrl(for blockId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_fileUrl__for_blockId(`blockId`), performs: perform) + } + public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, perform: @escaping ([CourseSequential]) -> Void) -> Perform { + return Perform(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), performs: perform) + } + public static func resumeDownloading(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_resumeDownloading, performs: perform) + } + public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { + return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) + } + public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + } } - open func cancelDownloading(task: DownloadDataTask) throws { - addInvocation(.m_cancelDownloading__task_task(Parameter.value(`task`))) - let perform = methodPerformValue(.m_cancelDownloading__task_task(Parameter.value(`task`))) as? (DownloadDataTask) -> Void - perform?(`task`) - do { - _ = try methodReturnValue(.m_cancelDownloading__task_task(Parameter.value(`task`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + public func given(_ method: Given) { + methodReturnValues.append(method) } - open func cancelDownloading(courseId: String) throws { - addInvocation(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))) - let perform = methodPerformValue(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))) as? (String) -> Void - perform?(`courseId`) - do { - _ = try methodReturnValue(.m_cancelDownloading__courseId_courseId(Parameter.value(`courseId`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } } - open func cancelAllDownloading() throws { - addInvocation(.m_cancelAllDownloading) - let perform = methodPerformValue(.m_cancelAllDownloading) as? () -> Void - perform?() - do { - _ = try methodReturnValue(.m_cancelAllDownloading).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) } - open func deleteFile(blocks: [CourseBlock]) { - addInvocation(.m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) - let perform = methodPerformValue(.m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void - perform?(`blocks`) + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } } - - open func deleteAllFiles() { - addInvocation(.m_deleteAllFiles) - let perform = methodPerformValue(.m_deleteAllFiles) as? () -> Void - perform?() + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product } - - open func fileUrl(for blockId: String) -> URL? { - addInvocation(.m_fileUrl__for_blockId(Parameter.value(`blockId`))) - let perform = methodPerformValue(.m_fileUrl__for_blockId(Parameter.value(`blockId`))) as? (String) -> Void - perform?(`blockId`) - var __value: URL? = nil - do { - __value = try methodReturnValue(.m_fileUrl__for_blockId(Parameter.value(`blockId`))).casted() - } catch { - // do nothing - } - return __value + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs } - - open func updateUnzippedFileSize(for sequentials: [CourseSequential]) -> [CourseSequential] { - addInvocation(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))) - let perform = methodPerformValue(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))) as? ([CourseSequential]) -> Void - perform?(`sequentials`) - var __value: [CourseSequential] - do { - __value = try methodReturnValue(.m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>.value(`sequentials`))).casted() - } catch { - onFatalFailure("Stub return value not specified for updateUnzippedFileSize(for sequentials: [CourseSequential]). Use given") - Failure("Stub return value not specified for updateUnzippedFileSize(for sequentials: [CourseSequential]). Use given") - } - return __value + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } } - - open func resumeDownloading() throws { - addInvocation(.m_resumeDownloading) - let perform = methodPerformValue(.m_resumeDownloading) as? () -> Void - perform?() - do { - _ = try methodReturnValue(.m_resumeDownloading).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count } - - open func isLargeVideosSize(blocks: [CourseBlock]) -> Bool { - addInvocation(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) - let perform = methodPerformValue(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))) as? ([CourseBlock]) -> Void - perform?(`blocks`) - var __value: Bool - do { - __value = try methodReturnValue(.m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>.value(`blocks`))).casted() - } catch { - onFatalFailure("Stub return value not specified for isLargeVideosSize(blocks: [CourseBlock]). Use given") - Failure("Stub return value not specified for isLargeVideosSize(blocks: [CourseBlock]). Use given") - } - return __value + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } } - - open func removeAppSupportDirectoryUnusedContent() { - addInvocation(.m_removeAppSupportDirectoryUnusedContent) - let perform = methodPerformValue(.m_removeAppSupportDirectoryUnusedContent) as? () -> Void - perform?() + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} +// MARK: - OfflineSyncInteractorProtocol - fileprivate enum MethodType { - case m_publisher - case m_eventPublisher - case m_addToDownloadQueue__blocks_blocks(Parameter<[CourseBlock]>) - case m_getDownloadTasks - case m_getDownloadTasksForCourse__courseId(Parameter) - case m_cancelDownloading__courseId_courseIdblocks_blocks(Parameter, Parameter<[CourseBlock]>) - case m_cancelDownloading__task_task(Parameter) - case m_cancelDownloading__courseId_courseId(Parameter) - case m_cancelAllDownloading - case m_deleteFile__blocks_blocks(Parameter<[CourseBlock]>) - case m_deleteAllFiles - case m_fileUrl__for_blockId(Parameter) - case m_updateUnzippedFileSize__for_sequentials(Parameter<[CourseSequential]>) - case m_resumeDownloading - case m_isLargeVideosSize__blocks_blocks(Parameter<[CourseBlock]>) - case m_removeAppSupportDirectoryUnusedContent - case p_currentDownloadTask_get - - static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { - case (.m_publisher, .m_publisher): return .match - - case (.m_eventPublisher, .m_eventPublisher): return .match +open class OfflineSyncInteractorProtocolMock: OfflineSyncInteractorProtocol, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } - case (.m_addToDownloadQueue__blocks_blocks(let lhsBlocks), .m_addToDownloadQueue__blocks_blocks(let rhsBlocks)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) - return Matcher.ComparisonResult(results) + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst - case (.m_getDownloadTasks, .m_getDownloadTasks): return .match + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? - case (.m_getDownloadTasksForCourse__courseId(let lhsCourseid), .m_getDownloadTasksForCourse__courseId(let rhsCourseid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "_ courseId")) - return Matcher.ComparisonResult(results) + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given - case (.m_cancelDownloading__courseId_courseIdblocks_blocks(let lhsCourseid, let lhsBlocks), .m_cancelDownloading__courseId_courseIdblocks_blocks(let rhsCourseid, let rhsBlocks)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseId")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) - return Matcher.ComparisonResult(results) + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } - case (.m_cancelDownloading__task_task(let lhsTask), .m_cancelDownloading__task_task(let rhsTask)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsTask, rhs: rhsTask, with: matcher), lhsTask, rhsTask, "task")) - return Matcher.ComparisonResult(results) + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } - case (.m_cancelDownloading__courseId_courseId(let lhsCourseid), .m_cancelDownloading__courseId_courseId(let rhsCourseid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseId")) - return Matcher.ComparisonResult(results) - case (.m_cancelAllDownloading, .m_cancelAllDownloading): return .match - case (.m_deleteFile__blocks_blocks(let lhsBlocks), .m_deleteFile__blocks_blocks(let rhsBlocks)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) - return Matcher.ComparisonResult(results) - case (.m_deleteAllFiles, .m_deleteAllFiles): return .match - case (.m_fileUrl__for_blockId(let lhsBlockid), .m_fileUrl__for_blockId(let rhsBlockid)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "for blockId")) - return Matcher.ComparisonResult(results) + open func submitOfflineProgress(courseID: String, blockID: String, data: String) throws -> Bool { + addInvocation(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))) + let perform = methodPerformValue(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))) as? (String, String, String) -> Void + perform?(`courseID`, `blockID`, `data`) + var __value: Bool + do { + __value = try methodReturnValue(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for submitOfflineProgress(courseID: String, blockID: String, data: String). Use given") + Failure("Stub return value not specified for submitOfflineProgress(courseID: String, blockID: String, data: String). Use given") + } catch { + throw error + } + return __value + } - case (.m_updateUnzippedFileSize__for_sequentials(let lhsSequentials), .m_updateUnzippedFileSize__for_sequentials(let rhsSequentials)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSequentials, rhs: rhsSequentials, with: matcher), lhsSequentials, rhsSequentials, "for sequentials")) - return Matcher.ComparisonResult(results) - case (.m_resumeDownloading, .m_resumeDownloading): return .match + fileprivate enum MethodType { + case m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter, Parameter, Parameter) - case (.m_isLargeVideosSize__blocks_blocks(let lhsBlocks), .m_isLargeVideosSize__blocks_blocks(let rhsBlocks)): + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(let lhsCourseid, let lhsBlockid, let lhsData), .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(let rhsCourseid, let rhsBlockid, let rhsData)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlocks, rhs: rhsBlocks, with: matcher), lhsBlocks, rhsBlocks, "blocks")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "blockID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsData, rhs: rhsData, with: matcher), lhsData, rhsData, "data")) return Matcher.ComparisonResult(results) - - case (.m_removeAppSupportDirectoryUnusedContent, .m_removeAppSupportDirectoryUnusedContent): return .match - case (.p_currentDownloadTask_get,.p_currentDownloadTask_get): return Matcher.ComparisonResult.match - default: return .none } } func intValue() -> Int { switch self { - case .m_publisher: return 0 - case .m_eventPublisher: return 0 - case let .m_addToDownloadQueue__blocks_blocks(p0): return p0.intValue - case .m_getDownloadTasks: return 0 - case let .m_getDownloadTasksForCourse__courseId(p0): return p0.intValue - case let .m_cancelDownloading__courseId_courseIdblocks_blocks(p0, p1): return p0.intValue + p1.intValue - case let .m_cancelDownloading__task_task(p0): return p0.intValue - case let .m_cancelDownloading__courseId_courseId(p0): return p0.intValue - case .m_cancelAllDownloading: return 0 - case let .m_deleteFile__blocks_blocks(p0): return p0.intValue - case .m_deleteAllFiles: return 0 - case let .m_fileUrl__for_blockId(p0): return p0.intValue - case let .m_updateUnzippedFileSize__for_sequentials(p0): return p0.intValue - case .m_resumeDownloading: return 0 - case let .m_isLargeVideosSize__blocks_blocks(p0): return p0.intValue - case .m_removeAppSupportDirectoryUnusedContent: return 0 - case .p_currentDownloadTask_get: return 0 - } - } - func assertionName() -> String { - switch self { - case .m_publisher: return ".publisher()" - case .m_eventPublisher: return ".eventPublisher()" - case .m_addToDownloadQueue__blocks_blocks: return ".addToDownloadQueue(blocks:)" - case .m_getDownloadTasks: return ".getDownloadTasks()" - case .m_getDownloadTasksForCourse__courseId: return ".getDownloadTasksForCourse(_:)" - case .m_cancelDownloading__courseId_courseIdblocks_blocks: return ".cancelDownloading(courseId:blocks:)" - case .m_cancelDownloading__task_task: return ".cancelDownloading(task:)" - case .m_cancelDownloading__courseId_courseId: return ".cancelDownloading(courseId:)" - case .m_cancelAllDownloading: return ".cancelAllDownloading()" - case .m_deleteFile__blocks_blocks: return ".deleteFile(blocks:)" - case .m_deleteAllFiles: return ".deleteAllFiles()" - case .m_fileUrl__for_blockId: return ".fileUrl(for:)" - case .m_updateUnzippedFileSize__for_sequentials: return ".updateUnzippedFileSize(for:)" - case .m_resumeDownloading: return ".resumeDownloading()" - case .m_isLargeVideosSize__blocks_blocks: return ".isLargeVideosSize(blocks:)" - case .m_removeAppSupportDirectoryUnusedContent: return ".removeAppSupportDirectoryUnusedContent()" - case .p_currentDownloadTask_get: return "[get] .currentDownloadTask" + case let .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue } } - } - - open class Given: StubbedMethod { - fileprivate var method: MethodType - - private init(method: MethodType, products: [StubProduct]) { - self.method = method - super.init(products) - } - - public static func currentDownloadTask(getter defaultValue: DownloadDataTask?...) -> PropertyStub { - return Given(method: .p_currentDownloadTask_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) - } - - public static func publisher(willReturn: AnyPublisher...) -> MethodStub { - return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func eventPublisher(willReturn: AnyPublisher...) -> MethodStub { - return Given(method: .m_eventPublisher, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getDownloadTasks(willReturn: [DownloadDataTask]...) -> MethodStub { - return Given(method: .m_getDownloadTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getDownloadTasksForCourse(_ courseId: Parameter, willReturn: [DownloadDataTask]...) -> MethodStub { - return Given(method: .m_getDownloadTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func fileUrl(for blockId: Parameter, willReturn: URL?...) -> MethodStub { - return Given(method: .m_fileUrl__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, willReturn: [CourseSequential]...) -> MethodStub { - return Given(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, willReturn: Bool...) -> MethodStub { - return Given(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func publisher(willProduce: (Stubber>) -> Void) -> MethodStub { - let willReturn: [AnyPublisher] = [] - let given: Given = { return Given(method: .m_publisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (AnyPublisher).self) - willProduce(stubber) - return given - } - public static func eventPublisher(willProduce: (Stubber>) -> Void) -> MethodStub { - let willReturn: [AnyPublisher] = [] - let given: Given = { return Given(method: .m_eventPublisher, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (AnyPublisher).self) - willProduce(stubber) - return given - } - public static func getDownloadTasks(willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { - let willReturn: [[DownloadDataTask]] = [] - let given: Given = { return Given(method: .m_getDownloadTasks, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([DownloadDataTask]).self) - willProduce(stubber) - return given - } - public static func getDownloadTasksForCourse(_ courseId: Parameter, willProduce: (Stubber<[DownloadDataTask]>) -> Void) -> MethodStub { - let willReturn: [[DownloadDataTask]] = [] - let given: Given = { return Given(method: .m_getDownloadTasksForCourse__courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([DownloadDataTask]).self) - willProduce(stubber) - return given - } - public static func fileUrl(for blockId: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [URL?] = [] - let given: Given = { return Given(method: .m_fileUrl__for_blockId(`blockId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (URL?).self) - willProduce(stubber) - return given - } - public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, willProduce: (Stubber<[CourseSequential]>) -> Void) -> MethodStub { - let willReturn: [[CourseSequential]] = [] - let given: Given = { return Given(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([CourseSequential]).self) - willProduce(stubber) - return given - } - public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [Bool] = [] - let given: Given = { return Given(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (Bool).self) - willProduce(stubber) - return given - } - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, willThrow: Error...) -> MethodStub { - return Given(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, willThrow: Error...) -> MethodStub { - return Given(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - public static func cancelDownloading(task: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_cancelDownloading__task_task(`task`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func cancelDownloading(task: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_cancelDownloading__task_task(`task`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - public static func cancelDownloading(courseId: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_cancelDownloading__courseId_courseId(`courseId`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func cancelDownloading(courseId: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_cancelDownloading__courseId_courseId(`courseId`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given + func assertionName() -> String { + switch self { + case .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data: return ".submitOfflineProgress(courseID:blockID:data:)" + } } - public static func cancelAllDownloading(willThrow: Error...) -> MethodStub { - return Given(method: .m_cancelAllDownloading, products: willThrow.map({ StubProduct.throw($0) })) + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) } - public static func cancelAllDownloading(willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_cancelAllDownloading, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given + + + public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willReturn.map({ StubProduct.return($0 as Any) })) } - public static func resumeDownloading(willThrow: Error...) -> MethodStub { - return Given(method: .m_resumeDownloading, products: willThrow.map({ StubProduct.throw($0) })) + public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willThrow.map({ StubProduct.throw($0) })) } - public static func resumeDownloading(willProduce: (StubberThrows) -> Void) -> MethodStub { + public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_resumeDownloading, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) + let given: Given = { return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Bool).self) willProduce(stubber) return given } @@ -3049,76 +4202,15 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { public struct Verify { fileprivate var method: MethodType - public static func publisher() -> Verify { return Verify(method: .m_publisher)} - public static func eventPublisher() -> Verify { return Verify(method: .m_eventPublisher)} - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_addToDownloadQueue__blocks_blocks(`blocks`))} - public static func getDownloadTasks() -> Verify { return Verify(method: .m_getDownloadTasks)} - public static func getDownloadTasksForCourse(_ courseId: Parameter) -> Verify { return Verify(method: .m_getDownloadTasksForCourse__courseId(`courseId`))} - public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`))} - public static func cancelDownloading(task: Parameter) -> Verify { return Verify(method: .m_cancelDownloading__task_task(`task`))} - public static func cancelDownloading(courseId: Parameter) -> Verify { return Verify(method: .m_cancelDownloading__courseId_courseId(`courseId`))} - public static func cancelAllDownloading() -> Verify { return Verify(method: .m_cancelAllDownloading)} - public static func deleteFile(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_deleteFile__blocks_blocks(`blocks`))} - public static func deleteAllFiles() -> Verify { return Verify(method: .m_deleteAllFiles)} - public static func fileUrl(for blockId: Parameter) -> Verify { return Verify(method: .m_fileUrl__for_blockId(`blockId`))} - public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>) -> Verify { return Verify(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`))} - public static func resumeDownloading() -> Verify { return Verify(method: .m_resumeDownloading)} - public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>) -> Verify { return Verify(method: .m_isLargeVideosSize__blocks_blocks(`blocks`))} - public static func removeAppSupportDirectoryUnusedContent() -> Verify { return Verify(method: .m_removeAppSupportDirectoryUnusedContent)} - public static var currentDownloadTask: Verify { return Verify(method: .p_currentDownloadTask_get) } + public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter) -> Verify { return Verify(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`))} } public struct Perform { fileprivate var method: MethodType var performs: Any - public static func publisher(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_publisher, performs: perform) - } - public static func eventPublisher(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_eventPublisher, performs: perform) - } - public static func addToDownloadQueue(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { - return Perform(method: .m_addToDownloadQueue__blocks_blocks(`blocks`), performs: perform) - } - public static func getDownloadTasks(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getDownloadTasks, performs: perform) - } - public static func getDownloadTasksForCourse(_ courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_getDownloadTasksForCourse__courseId(`courseId`), performs: perform) - } - public static func cancelDownloading(courseId: Parameter, blocks: Parameter<[CourseBlock]>, perform: @escaping (String, [CourseBlock]) -> Void) -> Perform { - return Perform(method: .m_cancelDownloading__courseId_courseIdblocks_blocks(`courseId`, `blocks`), performs: perform) - } - public static func cancelDownloading(task: Parameter, perform: @escaping (DownloadDataTask) -> Void) -> Perform { - return Perform(method: .m_cancelDownloading__task_task(`task`), performs: perform) - } - public static func cancelDownloading(courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_cancelDownloading__courseId_courseId(`courseId`), performs: perform) - } - public static func cancelAllDownloading(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_cancelAllDownloading, performs: perform) - } - public static func deleteFile(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { - return Perform(method: .m_deleteFile__blocks_blocks(`blocks`), performs: perform) - } - public static func deleteAllFiles(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_deleteAllFiles, performs: perform) - } - public static func fileUrl(for blockId: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_fileUrl__for_blockId(`blockId`), performs: perform) - } - public static func updateUnzippedFileSize(for sequentials: Parameter<[CourseSequential]>, perform: @escaping ([CourseSequential]) -> Void) -> Perform { - return Perform(method: .m_updateUnzippedFileSize__for_sequentials(`sequentials`), performs: perform) - } - public static func resumeDownloading(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_resumeDownloading, performs: perform) - } - public static func isLargeVideosSize(blocks: Parameter<[CourseBlock]>, perform: @escaping ([CourseBlock]) -> Void) -> Perform { - return Perform(method: .m_isLargeVideosSize__blocks_blocks(`blocks`), performs: perform) - } - public static func removeAppSupportDirectoryUnusedContent(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_removeAppSupportDirectoryUnusedContent, performs: perform) + public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, perform: @escaping (String, String, String) -> Void) -> Perform { + return Perform(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), performs: perform) } } @@ -3195,89 +4287,271 @@ open class DownloadManagerProtocolMock: DownloadManagerProtocol, Mock { } } -// MARK: - OfflineSyncInteractorProtocol +// MARK: - ProfileAnalytics + +open class ProfileAnalyticsMock: ProfileAnalytics, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + + + + + open func profileEditClicked() { + addInvocation(.m_profileEditClicked) + let perform = methodPerformValue(.m_profileEditClicked) as? () -> Void + perform?() + } + + open func profileSwitch(action: String) { + addInvocation(.m_profileSwitch__action_action(Parameter.value(`action`))) + let perform = methodPerformValue(.m_profileSwitch__action_action(Parameter.value(`action`))) as? (String) -> Void + perform?(`action`) + } + + open func profileEditDoneClicked() { + addInvocation(.m_profileEditDoneClicked) + let perform = methodPerformValue(.m_profileEditDoneClicked) as? () -> Void + perform?() + } + + open func profileDeleteAccountClicked() { + addInvocation(.m_profileDeleteAccountClicked) + let perform = methodPerformValue(.m_profileDeleteAccountClicked) as? () -> Void + perform?() + } + + open func profileVideoSettingsClicked() { + addInvocation(.m_profileVideoSettingsClicked) + let perform = methodPerformValue(.m_profileVideoSettingsClicked) as? () -> Void + perform?() + } + + open func privacyPolicyClicked() { + addInvocation(.m_privacyPolicyClicked) + let perform = methodPerformValue(.m_privacyPolicyClicked) as? () -> Void + perform?() + } + + open func cookiePolicyClicked() { + addInvocation(.m_cookiePolicyClicked) + let perform = methodPerformValue(.m_cookiePolicyClicked) as? () -> Void + perform?() + } + + open func emailSupportClicked() { + addInvocation(.m_emailSupportClicked) + let perform = methodPerformValue(.m_emailSupportClicked) as? () -> Void + perform?() + } + + open func faqClicked() { + addInvocation(.m_faqClicked) + let perform = methodPerformValue(.m_faqClicked) as? () -> Void + perform?() + } + + open func tosClicked() { + addInvocation(.m_tosClicked) + let perform = methodPerformValue(.m_tosClicked) as? () -> Void + perform?() + } + + open func dataSellClicked() { + addInvocation(.m_dataSellClicked) + let perform = methodPerformValue(.m_dataSellClicked) as? () -> Void + perform?() + } + + open func userLogout(force: Bool) { + addInvocation(.m_userLogout__force_force(Parameter.value(`force`))) + let perform = methodPerformValue(.m_userLogout__force_force(Parameter.value(`force`))) as? (Bool) -> Void + perform?(`force`) + } + + open func profileWifiToggle(action: String) { + addInvocation(.m_profileWifiToggle__action_action(Parameter.value(`action`))) + let perform = methodPerformValue(.m_profileWifiToggle__action_action(Parameter.value(`action`))) as? (String) -> Void + perform?(`action`) + } + + open func profileUserDeleteAccountClicked() { + addInvocation(.m_profileUserDeleteAccountClicked) + let perform = methodPerformValue(.m_profileUserDeleteAccountClicked) as? () -> Void + perform?() + } + + open func profileDeleteAccountSuccess(success: Bool) { + addInvocation(.m_profileDeleteAccountSuccess__success_success(Parameter.value(`success`))) + let perform = methodPerformValue(.m_profileDeleteAccountSuccess__success_success(Parameter.value(`success`))) as? (Bool) -> Void + perform?(`success`) + } + + open func profileTrackEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { + addInvocation(.m_profileTrackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) + let perform = methodPerformValue(.m_profileTrackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void + perform?(`event`, `biValue`) + } + + open func profileScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { + addInvocation(.m_profileScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) + let perform = methodPerformValue(.m_profileScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void + perform?(`event`, `biValue`) + } + + + fileprivate enum MethodType { + case m_profileEditClicked + case m_profileSwitch__action_action(Parameter) + case m_profileEditDoneClicked + case m_profileDeleteAccountClicked + case m_profileVideoSettingsClicked + case m_privacyPolicyClicked + case m_cookiePolicyClicked + case m_emailSupportClicked + case m_faqClicked + case m_tosClicked + case m_dataSellClicked + case m_userLogout__force_force(Parameter) + case m_profileWifiToggle__action_action(Parameter) + case m_profileUserDeleteAccountClicked + case m_profileDeleteAccountSuccess__success_success(Parameter) + case m_profileTrackEvent__eventbiValue_biValue(Parameter, Parameter) + case m_profileScreenEvent__eventbiValue_biValue(Parameter, Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { + case (.m_profileEditClicked, .m_profileEditClicked): return .match -open class OfflineSyncInteractorProtocolMock: OfflineSyncInteractorProtocol, Mock { - public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { - SwiftyMockyTestObserver.setup() - self.sequencingPolicy = sequencingPolicy - self.stubbingPolicy = stubbingPolicy - self.file = file - self.line = line - } + case (.m_profileSwitch__action_action(let lhsAction), .m_profileSwitch__action_action(let rhsAction)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) + return Matcher.ComparisonResult(results) - var matcher: Matcher = Matcher.default - var stubbingPolicy: StubbingPolicy = .wrap - var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + case (.m_profileEditDoneClicked, .m_profileEditDoneClicked): return .match - private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) - private var invocations: [MethodType] = [] - private var methodReturnValues: [Given] = [] - private var methodPerformValues: [Perform] = [] - private var file: StaticString? - private var line: UInt? + case (.m_profileDeleteAccountClicked, .m_profileDeleteAccountClicked): return .match - public typealias PropertyStub = Given - public typealias MethodStub = Given - public typealias SubscriptStub = Given + case (.m_profileVideoSettingsClicked, .m_profileVideoSettingsClicked): return .match - /// Convenience method - call setupMock() to extend debug information when failure occurs - public func setupMock(file: StaticString = #file, line: UInt = #line) { - self.file = file - self.line = line - } + case (.m_privacyPolicyClicked, .m_privacyPolicyClicked): return .match - /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals - public func resetMock(_ scopes: MockScope...) { - let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes - if scopes.contains(.invocation) { invocations = [] } - if scopes.contains(.given) { methodReturnValues = [] } - if scopes.contains(.perform) { methodPerformValues = [] } - } + case (.m_cookiePolicyClicked, .m_cookiePolicyClicked): return .match + + case (.m_emailSupportClicked, .m_emailSupportClicked): return .match + case (.m_faqClicked, .m_faqClicked): return .match + case (.m_tosClicked, .m_tosClicked): return .match + case (.m_dataSellClicked, .m_dataSellClicked): return .match + case (.m_userLogout__force_force(let lhsForce), .m_userLogout__force_force(let rhsForce)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsForce, rhs: rhsForce, with: matcher), lhsForce, rhsForce, "force")) + return Matcher.ComparisonResult(results) - open func submitOfflineProgress(courseID: String, blockID: String, data: String) throws -> Bool { - addInvocation(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))) - let perform = methodPerformValue(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))) as? (String, String, String) -> Void - perform?(`courseID`, `blockID`, `data`) - var __value: Bool - do { - __value = try methodReturnValue(.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter.value(`courseID`), Parameter.value(`blockID`), Parameter.value(`data`))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for submitOfflineProgress(courseID: String, blockID: String, data: String). Use given") - Failure("Stub return value not specified for submitOfflineProgress(courseID: String, blockID: String, data: String). Use given") - } catch { - throw error - } - return __value - } + case (.m_profileWifiToggle__action_action(let lhsAction), .m_profileWifiToggle__action_action(let rhsAction)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) + return Matcher.ComparisonResult(results) + case (.m_profileUserDeleteAccountClicked, .m_profileUserDeleteAccountClicked): return .match - fileprivate enum MethodType { - case m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(Parameter, Parameter, Parameter) + case (.m_profileDeleteAccountSuccess__success_success(let lhsSuccess), .m_profileDeleteAccountSuccess__success_success(let rhsSuccess)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSuccess, rhs: rhsSuccess, with: matcher), lhsSuccess, rhsSuccess, "success")) + return Matcher.ComparisonResult(results) - static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { - switch (lhs, rhs) { - case (.m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(let lhsCourseid, let lhsBlockid, let lhsData), .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(let rhsCourseid, let rhsBlockid, let rhsData)): + case (.m_profileTrackEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_profileTrackEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBlockid, rhs: rhsBlockid, with: matcher), lhsBlockid, rhsBlockid, "blockID")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsData, rhs: rhsData, with: matcher), lhsData, rhsData, "data")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + return Matcher.ComparisonResult(results) + + case (.m_profileScreenEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_profileScreenEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) return Matcher.ComparisonResult(results) + default: return .none } } func intValue() -> Int { switch self { - case let .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(p0, p1, p2): return p0.intValue + p1.intValue + p2.intValue + case .m_profileEditClicked: return 0 + case let .m_profileSwitch__action_action(p0): return p0.intValue + case .m_profileEditDoneClicked: return 0 + case .m_profileDeleteAccountClicked: return 0 + case .m_profileVideoSettingsClicked: return 0 + case .m_privacyPolicyClicked: return 0 + case .m_cookiePolicyClicked: return 0 + case .m_emailSupportClicked: return 0 + case .m_faqClicked: return 0 + case .m_tosClicked: return 0 + case .m_dataSellClicked: return 0 + case let .m_userLogout__force_force(p0): return p0.intValue + case let .m_profileWifiToggle__action_action(p0): return p0.intValue + case .m_profileUserDeleteAccountClicked: return 0 + case let .m_profileDeleteAccountSuccess__success_success(p0): return p0.intValue + case let .m_profileTrackEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue + case let .m_profileScreenEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue } } func assertionName() -> String { switch self { - case .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data: return ".submitOfflineProgress(courseID:blockID:data:)" + case .m_profileEditClicked: return ".profileEditClicked()" + case .m_profileSwitch__action_action: return ".profileSwitch(action:)" + case .m_profileEditDoneClicked: return ".profileEditDoneClicked()" + case .m_profileDeleteAccountClicked: return ".profileDeleteAccountClicked()" + case .m_profileVideoSettingsClicked: return ".profileVideoSettingsClicked()" + case .m_privacyPolicyClicked: return ".privacyPolicyClicked()" + case .m_cookiePolicyClicked: return ".cookiePolicyClicked()" + case .m_emailSupportClicked: return ".emailSupportClicked()" + case .m_faqClicked: return ".faqClicked()" + case .m_tosClicked: return ".tosClicked()" + case .m_dataSellClicked: return ".dataSellClicked()" + case .m_userLogout__force_force: return ".userLogout(force:)" + case .m_profileWifiToggle__action_action: return ".profileWifiToggle(action:)" + case .m_profileUserDeleteAccountClicked: return ".profileUserDeleteAccountClicked()" + case .m_profileDeleteAccountSuccess__success_success: return ".profileDeleteAccountSuccess(success:)" + case .m_profileTrackEvent__eventbiValue_biValue: return ".profileTrackEvent(_:biValue:)" + case .m_profileScreenEvent__eventbiValue_biValue: return ".profileScreenEvent(_:biValue:)" } } } @@ -3291,33 +4565,84 @@ open class OfflineSyncInteractorProtocolMock: OfflineSyncInteractorProtocol, Moc } - public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willReturn: Bool...) -> MethodStub { - return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Bool).self) - willProduce(stubber) - return given - } } public struct Verify { fileprivate var method: MethodType - public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter) -> Verify { return Verify(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`))} + public static func profileEditClicked() -> Verify { return Verify(method: .m_profileEditClicked)} + public static func profileSwitch(action: Parameter) -> Verify { return Verify(method: .m_profileSwitch__action_action(`action`))} + public static func profileEditDoneClicked() -> Verify { return Verify(method: .m_profileEditDoneClicked)} + public static func profileDeleteAccountClicked() -> Verify { return Verify(method: .m_profileDeleteAccountClicked)} + public static func profileVideoSettingsClicked() -> Verify { return Verify(method: .m_profileVideoSettingsClicked)} + public static func privacyPolicyClicked() -> Verify { return Verify(method: .m_privacyPolicyClicked)} + public static func cookiePolicyClicked() -> Verify { return Verify(method: .m_cookiePolicyClicked)} + public static func emailSupportClicked() -> Verify { return Verify(method: .m_emailSupportClicked)} + public static func faqClicked() -> Verify { return Verify(method: .m_faqClicked)} + public static func tosClicked() -> Verify { return Verify(method: .m_tosClicked)} + public static func dataSellClicked() -> Verify { return Verify(method: .m_dataSellClicked)} + public static func userLogout(force: Parameter) -> Verify { return Verify(method: .m_userLogout__force_force(`force`))} + public static func profileWifiToggle(action: Parameter) -> Verify { return Verify(method: .m_profileWifiToggle__action_action(`action`))} + public static func profileUserDeleteAccountClicked() -> Verify { return Verify(method: .m_profileUserDeleteAccountClicked)} + public static func profileDeleteAccountSuccess(success: Parameter) -> Verify { return Verify(method: .m_profileDeleteAccountSuccess__success_success(`success`))} + public static func profileTrackEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_profileTrackEvent__eventbiValue_biValue(`event`, `biValue`))} + public static func profileScreenEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_profileScreenEvent__eventbiValue_biValue(`event`, `biValue`))} } public struct Perform { fileprivate var method: MethodType var performs: Any - public static func submitOfflineProgress(courseID: Parameter, blockID: Parameter, data: Parameter, perform: @escaping (String, String, String) -> Void) -> Perform { - return Perform(method: .m_submitOfflineProgress__courseID_courseIDblockID_blockIDdata_data(`courseID`, `blockID`, `data`), performs: perform) + public static func profileEditClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_profileEditClicked, performs: perform) + } + public static func profileSwitch(action: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_profileSwitch__action_action(`action`), performs: perform) + } + public static func profileEditDoneClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_profileEditDoneClicked, performs: perform) + } + public static func profileDeleteAccountClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_profileDeleteAccountClicked, performs: perform) + } + public static func profileVideoSettingsClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_profileVideoSettingsClicked, performs: perform) + } + public static func privacyPolicyClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_privacyPolicyClicked, performs: perform) + } + public static func cookiePolicyClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_cookiePolicyClicked, performs: perform) + } + public static func emailSupportClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_emailSupportClicked, performs: perform) + } + public static func faqClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_faqClicked, performs: perform) + } + public static func tosClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_tosClicked, performs: perform) + } + public static func dataSellClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_dataSellClicked, performs: perform) + } + public static func userLogout(force: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_userLogout__force_force(`force`), performs: perform) + } + public static func profileWifiToggle(action: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_profileWifiToggle__action_action(`action`), performs: perform) + } + public static func profileUserDeleteAccountClicked(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_profileUserDeleteAccountClicked, performs: perform) + } + public static func profileDeleteAccountSuccess(success: Parameter, perform: @escaping (Bool) -> Void) -> Perform { + return Perform(method: .m_profileDeleteAccountSuccess__success_success(`success`), performs: perform) + } + public static func profileTrackEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { + return Perform(method: .m_profileTrackEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) + } + public static func profileScreenEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { + return Perform(method: .m_profileScreenEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) } } @@ -3394,9 +4719,9 @@ open class OfflineSyncInteractorProtocolMock: OfflineSyncInteractorProtocol, Moc } } -// MARK: - ProfileAnalytics +// MARK: - ProfileInteractorProtocol -open class ProfileAnalyticsMock: ProfileAnalytics, Mock { +open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -3436,184 +4761,270 @@ open class ProfileAnalyticsMock: ProfileAnalytics, Mock { - - - open func profileEditClicked() { - addInvocation(.m_profileEditClicked) - let perform = methodPerformValue(.m_profileEditClicked) as? () -> Void - perform?() - } - - open func profileSwitch(action: String) { - addInvocation(.m_profileSwitch__action_action(Parameter.value(`action`))) - let perform = methodPerformValue(.m_profileSwitch__action_action(Parameter.value(`action`))) as? (String) -> Void - perform?(`action`) - } - - open func profileEditDoneClicked() { - addInvocation(.m_profileEditDoneClicked) - let perform = methodPerformValue(.m_profileEditDoneClicked) as? () -> Void - perform?() - } - - open func profileDeleteAccountClicked() { - addInvocation(.m_profileDeleteAccountClicked) - let perform = methodPerformValue(.m_profileDeleteAccountClicked) as? () -> Void - perform?() + + + open func getUserProfile(username: String) throws -> UserProfile { + addInvocation(.m_getUserProfile__username_username(Parameter.value(`username`))) + let perform = methodPerformValue(.m_getUserProfile__username_username(Parameter.value(`username`))) as? (String) -> Void + perform?(`username`) + var __value: UserProfile + do { + __value = try methodReturnValue(.m_getUserProfile__username_username(Parameter.value(`username`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for getUserProfile(username: String). Use given") + Failure("Stub return value not specified for getUserProfile(username: String). Use given") + } catch { + throw error + } + return __value } - open func profileVideoSettingsClicked() { - addInvocation(.m_profileVideoSettingsClicked) - let perform = methodPerformValue(.m_profileVideoSettingsClicked) as? () -> Void + open func getMyProfile() throws -> UserProfile { + addInvocation(.m_getMyProfile) + let perform = methodPerformValue(.m_getMyProfile) as? () -> Void perform?() + var __value: UserProfile + do { + __value = try methodReturnValue(.m_getMyProfile).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for getMyProfile(). Use given") + Failure("Stub return value not specified for getMyProfile(). Use given") + } catch { + throw error + } + return __value } - open func privacyPolicyClicked() { - addInvocation(.m_privacyPolicyClicked) - let perform = methodPerformValue(.m_privacyPolicyClicked) as? () -> Void + open func getMyProfileOffline() -> UserProfile? { + addInvocation(.m_getMyProfileOffline) + let perform = methodPerformValue(.m_getMyProfileOffline) as? () -> Void perform?() + var __value: UserProfile? = nil + do { + __value = try methodReturnValue(.m_getMyProfileOffline).casted() + } catch { + // do nothing + } + return __value } - open func cookiePolicyClicked() { - addInvocation(.m_cookiePolicyClicked) - let perform = methodPerformValue(.m_cookiePolicyClicked) as? () -> Void + open func logOut() throws { + addInvocation(.m_logOut) + let perform = methodPerformValue(.m_logOut) as? () -> Void perform?() + do { + _ = try methodReturnValue(.m_logOut).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } } - open func emailSupportClicked() { - addInvocation(.m_emailSupportClicked) - let perform = methodPerformValue(.m_emailSupportClicked) as? () -> Void + open func getSpokenLanguages() -> [PickerFields.Option] { + addInvocation(.m_getSpokenLanguages) + let perform = methodPerformValue(.m_getSpokenLanguages) as? () -> Void perform?() + var __value: [PickerFields.Option] + do { + __value = try methodReturnValue(.m_getSpokenLanguages).casted() + } catch { + onFatalFailure("Stub return value not specified for getSpokenLanguages(). Use given") + Failure("Stub return value not specified for getSpokenLanguages(). Use given") + } + return __value } - open func faqClicked() { - addInvocation(.m_faqClicked) - let perform = methodPerformValue(.m_faqClicked) as? () -> Void + open func getCountries() -> [PickerFields.Option] { + addInvocation(.m_getCountries) + let perform = methodPerformValue(.m_getCountries) as? () -> Void perform?() + var __value: [PickerFields.Option] + do { + __value = try methodReturnValue(.m_getCountries).casted() + } catch { + onFatalFailure("Stub return value not specified for getCountries(). Use given") + Failure("Stub return value not specified for getCountries(). Use given") + } + return __value } - open func tosClicked() { - addInvocation(.m_tosClicked) - let perform = methodPerformValue(.m_tosClicked) as? () -> Void - perform?() + open func uploadProfilePicture(pictureData: Data) throws { + addInvocation(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))) + let perform = methodPerformValue(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))) as? (Data) -> Void + perform?(`pictureData`) + do { + _ = try methodReturnValue(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))).casted() as Void + } catch MockError.notStubed { + // do nothing + } catch { + throw error + } } - open func dataSellClicked() { - addInvocation(.m_dataSellClicked) - let perform = methodPerformValue(.m_dataSellClicked) as? () -> Void + open func deleteProfilePicture() throws -> Bool { + addInvocation(.m_deleteProfilePicture) + let perform = methodPerformValue(.m_deleteProfilePicture) as? () -> Void perform?() + var __value: Bool + do { + __value = try methodReturnValue(.m_deleteProfilePicture).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for deleteProfilePicture(). Use given") + Failure("Stub return value not specified for deleteProfilePicture(). Use given") + } catch { + throw error + } + return __value } - open func userLogout(force: Bool) { - addInvocation(.m_userLogout__force_force(Parameter.value(`force`))) - let perform = methodPerformValue(.m_userLogout__force_force(Parameter.value(`force`))) as? (Bool) -> Void - perform?(`force`) + open func updateUserProfile(parameters: [String: Any]) throws -> UserProfile { + addInvocation(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))) + let perform = methodPerformValue(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))) as? ([String: Any]) -> Void + perform?(`parameters`) + var __value: UserProfile + do { + __value = try methodReturnValue(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for updateUserProfile(parameters: [String: Any]). Use given") + Failure("Stub return value not specified for updateUserProfile(parameters: [String: Any]). Use given") + } catch { + throw error + } + return __value } - open func profileWifiToggle(action: String) { - addInvocation(.m_profileWifiToggle__action_action(Parameter.value(`action`))) - let perform = methodPerformValue(.m_profileWifiToggle__action_action(Parameter.value(`action`))) as? (String) -> Void - perform?(`action`) + open func deleteAccount(password: String) throws -> Bool { + addInvocation(.m_deleteAccount__password_password(Parameter.value(`password`))) + let perform = methodPerformValue(.m_deleteAccount__password_password(Parameter.value(`password`))) as? (String) -> Void + perform?(`password`) + var __value: Bool + do { + __value = try methodReturnValue(.m_deleteAccount__password_password(Parameter.value(`password`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for deleteAccount(password: String). Use given") + Failure("Stub return value not specified for deleteAccount(password: String). Use given") + } catch { + throw error + } + return __value } - open func profileUserDeleteAccountClicked() { - addInvocation(.m_profileUserDeleteAccountClicked) - let perform = methodPerformValue(.m_profileUserDeleteAccountClicked) as? () -> Void + open func getSettings() -> UserSettings { + addInvocation(.m_getSettings) + let perform = methodPerformValue(.m_getSettings) as? () -> Void perform?() + var __value: UserSettings + do { + __value = try methodReturnValue(.m_getSettings).casted() + } catch { + onFatalFailure("Stub return value not specified for getSettings(). Use given") + Failure("Stub return value not specified for getSettings(). Use given") + } + return __value } - open func profileDeleteAccountSuccess(success: Bool) { - addInvocation(.m_profileDeleteAccountSuccess__success_success(Parameter.value(`success`))) - let perform = methodPerformValue(.m_profileDeleteAccountSuccess__success_success(Parameter.value(`success`))) as? (Bool) -> Void - perform?(`success`) + open func saveSettings(_ settings: UserSettings) { + addInvocation(.m_saveSettings__settings(Parameter.value(`settings`))) + let perform = methodPerformValue(.m_saveSettings__settings(Parameter.value(`settings`))) as? (UserSettings) -> Void + perform?(`settings`) } - open func profileTrackEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { - addInvocation(.m_profileTrackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) - let perform = methodPerformValue(.m_profileTrackEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void - perform?(`event`, `biValue`) + open func enrollmentsStatus() throws -> [CourseForSync] { + addInvocation(.m_enrollmentsStatus) + let perform = methodPerformValue(.m_enrollmentsStatus) as? () -> Void + perform?() + var __value: [CourseForSync] + do { + __value = try methodReturnValue(.m_enrollmentsStatus).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for enrollmentsStatus(). Use given") + Failure("Stub return value not specified for enrollmentsStatus(). Use given") + } catch { + throw error + } + return __value } - open func profileScreenEvent(_ event: AnalyticsEvent, biValue: EventBIValue) { - addInvocation(.m_profileScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) - let perform = methodPerformValue(.m_profileScreenEvent__eventbiValue_biValue(Parameter.value(`event`), Parameter.value(`biValue`))) as? (AnalyticsEvent, EventBIValue) -> Void - perform?(`event`, `biValue`) + open func getCourseDates(courseID: String) throws -> CourseDates { + addInvocation(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: CourseDates + do { + __value = try methodReturnValue(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))).casted() + } catch MockError.notStubed { + onFatalFailure("Stub return value not specified for getCourseDates(courseID: String). Use given") + Failure("Stub return value not specified for getCourseDates(courseID: String). Use given") + } catch { + throw error + } + return __value } fileprivate enum MethodType { - case m_profileEditClicked - case m_profileSwitch__action_action(Parameter) - case m_profileEditDoneClicked - case m_profileDeleteAccountClicked - case m_profileVideoSettingsClicked - case m_privacyPolicyClicked - case m_cookiePolicyClicked - case m_emailSupportClicked - case m_faqClicked - case m_tosClicked - case m_dataSellClicked - case m_userLogout__force_force(Parameter) - case m_profileWifiToggle__action_action(Parameter) - case m_profileUserDeleteAccountClicked - case m_profileDeleteAccountSuccess__success_success(Parameter) - case m_profileTrackEvent__eventbiValue_biValue(Parameter, Parameter) - case m_profileScreenEvent__eventbiValue_biValue(Parameter, Parameter) + case m_getUserProfile__username_username(Parameter) + case m_getMyProfile + case m_getMyProfileOffline + case m_logOut + case m_getSpokenLanguages + case m_getCountries + case m_uploadProfilePicture__pictureData_pictureData(Parameter) + case m_deleteProfilePicture + case m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>) + case m_deleteAccount__password_password(Parameter) + case m_getSettings + case m_saveSettings__settings(Parameter) + case m_enrollmentsStatus + case m_getCourseDates__courseID_courseID(Parameter) static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { switch (lhs, rhs) { - case (.m_profileEditClicked, .m_profileEditClicked): return .match - - case (.m_profileSwitch__action_action(let lhsAction), .m_profileSwitch__action_action(let rhsAction)): + case (.m_getUserProfile__username_username(let lhsUsername), .m_getUserProfile__username_username(let rhsUsername)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) - return Matcher.ComparisonResult(results) - - case (.m_profileEditDoneClicked, .m_profileEditDoneClicked): return .match - - case (.m_profileDeleteAccountClicked, .m_profileDeleteAccountClicked): return .match + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUsername, rhs: rhsUsername, with: matcher), lhsUsername, rhsUsername, "username")) + return Matcher.ComparisonResult(results) - case (.m_profileVideoSettingsClicked, .m_profileVideoSettingsClicked): return .match + case (.m_getMyProfile, .m_getMyProfile): return .match - case (.m_privacyPolicyClicked, .m_privacyPolicyClicked): return .match + case (.m_getMyProfileOffline, .m_getMyProfileOffline): return .match - case (.m_cookiePolicyClicked, .m_cookiePolicyClicked): return .match + case (.m_logOut, .m_logOut): return .match - case (.m_emailSupportClicked, .m_emailSupportClicked): return .match + case (.m_getSpokenLanguages, .m_getSpokenLanguages): return .match - case (.m_faqClicked, .m_faqClicked): return .match + case (.m_getCountries, .m_getCountries): return .match - case (.m_tosClicked, .m_tosClicked): return .match + case (.m_uploadProfilePicture__pictureData_pictureData(let lhsPicturedata), .m_uploadProfilePicture__pictureData_pictureData(let rhsPicturedata)): + var results: [Matcher.ParameterComparisonResult] = [] + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsPicturedata, rhs: rhsPicturedata, with: matcher), lhsPicturedata, rhsPicturedata, "pictureData")) + return Matcher.ComparisonResult(results) - case (.m_dataSellClicked, .m_dataSellClicked): return .match + case (.m_deleteProfilePicture, .m_deleteProfilePicture): return .match - case (.m_userLogout__force_force(let lhsForce), .m_userLogout__force_force(let rhsForce)): + case (.m_updateUserProfile__parameters_parameters(let lhsParameters), .m_updateUserProfile__parameters_parameters(let rhsParameters)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsForce, rhs: rhsForce, with: matcher), lhsForce, rhsForce, "force")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) return Matcher.ComparisonResult(results) - case (.m_profileWifiToggle__action_action(let lhsAction), .m_profileWifiToggle__action_action(let rhsAction)): + case (.m_deleteAccount__password_password(let lhsPassword), .m_deleteAccount__password_password(let rhsPassword)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsAction, rhs: rhsAction, with: matcher), lhsAction, rhsAction, "action")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsPassword, rhs: rhsPassword, with: matcher), lhsPassword, rhsPassword, "password")) return Matcher.ComparisonResult(results) - case (.m_profileUserDeleteAccountClicked, .m_profileUserDeleteAccountClicked): return .match + case (.m_getSettings, .m_getSettings): return .match - case (.m_profileDeleteAccountSuccess__success_success(let lhsSuccess), .m_profileDeleteAccountSuccess__success_success(let rhsSuccess)): + case (.m_saveSettings__settings(let lhsSettings), .m_saveSettings__settings(let rhsSettings)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSuccess, rhs: rhsSuccess, with: matcher), lhsSuccess, rhsSuccess, "success")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSettings, rhs: rhsSettings, with: matcher), lhsSettings, rhsSettings, "_ settings")) return Matcher.ComparisonResult(results) - case (.m_profileTrackEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_profileTrackEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): - var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) - return Matcher.ComparisonResult(results) + case (.m_enrollmentsStatus, .m_enrollmentsStatus): return .match - case (.m_profileScreenEvent__eventbiValue_biValue(let lhsEvent, let lhsBivalue), .m_profileScreenEvent__eventbiValue_biValue(let rhsEvent, let rhsBivalue)): + case (.m_getCourseDates__courseID_courseID(let lhsCourseid), .m_getCourseDates__courseID_courseID(let rhsCourseid)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsBivalue, rhs: rhsBivalue, with: matcher), lhsBivalue, rhsBivalue, "biValue")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) return Matcher.ComparisonResult(results) default: return .none } @@ -3621,135 +5032,268 @@ open class ProfileAnalyticsMock: ProfileAnalytics, Mock { func intValue() -> Int { switch self { - case .m_profileEditClicked: return 0 - case let .m_profileSwitch__action_action(p0): return p0.intValue - case .m_profileEditDoneClicked: return 0 - case .m_profileDeleteAccountClicked: return 0 - case .m_profileVideoSettingsClicked: return 0 - case .m_privacyPolicyClicked: return 0 - case .m_cookiePolicyClicked: return 0 - case .m_emailSupportClicked: return 0 - case .m_faqClicked: return 0 - case .m_tosClicked: return 0 - case .m_dataSellClicked: return 0 - case let .m_userLogout__force_force(p0): return p0.intValue - case let .m_profileWifiToggle__action_action(p0): return p0.intValue - case .m_profileUserDeleteAccountClicked: return 0 - case let .m_profileDeleteAccountSuccess__success_success(p0): return p0.intValue - case let .m_profileTrackEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue - case let .m_profileScreenEvent__eventbiValue_biValue(p0, p1): return p0.intValue + p1.intValue + case let .m_getUserProfile__username_username(p0): return p0.intValue + case .m_getMyProfile: return 0 + case .m_getMyProfileOffline: return 0 + case .m_logOut: return 0 + case .m_getSpokenLanguages: return 0 + case .m_getCountries: return 0 + case let .m_uploadProfilePicture__pictureData_pictureData(p0): return p0.intValue + case .m_deleteProfilePicture: return 0 + case let .m_updateUserProfile__parameters_parameters(p0): return p0.intValue + case let .m_deleteAccount__password_password(p0): return p0.intValue + case .m_getSettings: return 0 + case let .m_saveSettings__settings(p0): return p0.intValue + case .m_enrollmentsStatus: return 0 + case let .m_getCourseDates__courseID_courseID(p0): return p0.intValue } } func assertionName() -> String { switch self { - case .m_profileEditClicked: return ".profileEditClicked()" - case .m_profileSwitch__action_action: return ".profileSwitch(action:)" - case .m_profileEditDoneClicked: return ".profileEditDoneClicked()" - case .m_profileDeleteAccountClicked: return ".profileDeleteAccountClicked()" - case .m_profileVideoSettingsClicked: return ".profileVideoSettingsClicked()" - case .m_privacyPolicyClicked: return ".privacyPolicyClicked()" - case .m_cookiePolicyClicked: return ".cookiePolicyClicked()" - case .m_emailSupportClicked: return ".emailSupportClicked()" - case .m_faqClicked: return ".faqClicked()" - case .m_tosClicked: return ".tosClicked()" - case .m_dataSellClicked: return ".dataSellClicked()" - case .m_userLogout__force_force: return ".userLogout(force:)" - case .m_profileWifiToggle__action_action: return ".profileWifiToggle(action:)" - case .m_profileUserDeleteAccountClicked: return ".profileUserDeleteAccountClicked()" - case .m_profileDeleteAccountSuccess__success_success: return ".profileDeleteAccountSuccess(success:)" - case .m_profileTrackEvent__eventbiValue_biValue: return ".profileTrackEvent(_:biValue:)" - case .m_profileScreenEvent__eventbiValue_biValue: return ".profileScreenEvent(_:biValue:)" + case .m_getUserProfile__username_username: return ".getUserProfile(username:)" + case .m_getMyProfile: return ".getMyProfile()" + case .m_getMyProfileOffline: return ".getMyProfileOffline()" + case .m_logOut: return ".logOut()" + case .m_getSpokenLanguages: return ".getSpokenLanguages()" + case .m_getCountries: return ".getCountries()" + case .m_uploadProfilePicture__pictureData_pictureData: return ".uploadProfilePicture(pictureData:)" + case .m_deleteProfilePicture: return ".deleteProfilePicture()" + case .m_updateUserProfile__parameters_parameters: return ".updateUserProfile(parameters:)" + case .m_deleteAccount__password_password: return ".deleteAccount(password:)" + case .m_getSettings: return ".getSettings()" + case .m_saveSettings__settings: return ".saveSettings(_:)" + case .m_enrollmentsStatus: return ".enrollmentsStatus()" + case .m_getCourseDates__courseID_courseID: return ".getCourseDates(courseID:)" } } - } - - open class Given: StubbedMethod { - fileprivate var method: MethodType - - private init(method: MethodType, products: [StubProduct]) { - self.method = method - super.init(products) + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + + public static func getUserProfile(username: Parameter, willReturn: UserProfile...) -> MethodStub { + return Given(method: .m_getUserProfile__username_username(`username`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getMyProfile(willReturn: UserProfile...) -> MethodStub { + return Given(method: .m_getMyProfile, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getMyProfileOffline(willReturn: UserProfile?...) -> MethodStub { + return Given(method: .m_getMyProfileOffline, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getSpokenLanguages(willReturn: [PickerFields.Option]...) -> MethodStub { + return Given(method: .m_getSpokenLanguages, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getCountries(willReturn: [PickerFields.Option]...) -> MethodStub { + return Given(method: .m_getCountries, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func deleteProfilePicture(willReturn: Bool...) -> MethodStub { + return Given(method: .m_deleteProfilePicture, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func updateUserProfile(parameters: Parameter<[String: Any]>, willReturn: UserProfile...) -> MethodStub { + return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func deleteAccount(password: Parameter, willReturn: Bool...) -> MethodStub { + return Given(method: .m_deleteAccount__password_password(`password`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getSettings(willReturn: UserSettings...) -> MethodStub { + return Given(method: .m_getSettings, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func enrollmentsStatus(willReturn: [CourseForSync]...) -> MethodStub { + return Given(method: .m_enrollmentsStatus, products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getCourseDates(courseID: Parameter, willReturn: CourseDates...) -> MethodStub { + return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getMyProfileOffline(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [UserProfile?] = [] + let given: Given = { return Given(method: .m_getMyProfileOffline, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (UserProfile?).self) + willProduce(stubber) + return given + } + public static func getSpokenLanguages(willProduce: (Stubber<[PickerFields.Option]>) -> Void) -> MethodStub { + let willReturn: [[PickerFields.Option]] = [] + let given: Given = { return Given(method: .m_getSpokenLanguages, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([PickerFields.Option]).self) + willProduce(stubber) + return given + } + public static func getCountries(willProduce: (Stubber<[PickerFields.Option]>) -> Void) -> MethodStub { + let willReturn: [[PickerFields.Option]] = [] + let given: Given = { return Given(method: .m_getCountries, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([PickerFields.Option]).self) + willProduce(stubber) + return given + } + public static func getSettings(willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [UserSettings] = [] + let given: Given = { return Given(method: .m_getSettings, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (UserSettings).self) + willProduce(stubber) + return given + } + public static func getUserProfile(username: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_getUserProfile__username_username(`username`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func getUserProfile(username: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_getUserProfile__username_username(`username`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (UserProfile).self) + willProduce(stubber) + return given + } + public static func getMyProfile(willThrow: Error...) -> MethodStub { + return Given(method: .m_getMyProfile, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func getMyProfile(willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_getMyProfile, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (UserProfile).self) + willProduce(stubber) + return given + } + public static func logOut(willThrow: Error...) -> MethodStub { + return Given(method: .m_logOut, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func logOut(willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_logOut, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func uploadProfilePicture(pictureData: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func uploadProfilePicture(pictureData: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Void).self) + willProduce(stubber) + return given + } + public static func deleteProfilePicture(willThrow: Error...) -> MethodStub { + return Given(method: .m_deleteProfilePicture, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func deleteProfilePicture(willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_deleteProfilePicture, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Bool).self) + willProduce(stubber) + return given + } + public static func updateUserProfile(parameters: Parameter<[String: Any]>, willThrow: Error...) -> MethodStub { + return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func updateUserProfile(parameters: Parameter<[String: Any]>, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (UserProfile).self) + willProduce(stubber) + return given + } + public static func deleteAccount(password: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_deleteAccount__password_password(`password`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func deleteAccount(password: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_deleteAccount__password_password(`password`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (Bool).self) + willProduce(stubber) + return given + } + public static func enrollmentsStatus(willThrow: Error...) -> MethodStub { + return Given(method: .m_enrollmentsStatus, products: willThrow.map({ StubProduct.throw($0) })) + } + public static func enrollmentsStatus(willProduce: (StubberThrows<[CourseForSync]>) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_enrollmentsStatus, products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: ([CourseForSync]).self) + willProduce(stubber) + return given + } + public static func getCourseDates(courseID: Parameter, willThrow: Error...) -> MethodStub { + return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willThrow.map({ StubProduct.throw($0) })) + } + public static func getCourseDates(courseID: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { + let willThrow: [Error] = [] + let given: Given = { return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willThrow.map({ StubProduct.throw($0) })) }() + let stubber = given.stubThrows(for: (CourseDates).self) + willProduce(stubber) + return given } - - } public struct Verify { fileprivate var method: MethodType - public static func profileEditClicked() -> Verify { return Verify(method: .m_profileEditClicked)} - public static func profileSwitch(action: Parameter) -> Verify { return Verify(method: .m_profileSwitch__action_action(`action`))} - public static func profileEditDoneClicked() -> Verify { return Verify(method: .m_profileEditDoneClicked)} - public static func profileDeleteAccountClicked() -> Verify { return Verify(method: .m_profileDeleteAccountClicked)} - public static func profileVideoSettingsClicked() -> Verify { return Verify(method: .m_profileVideoSettingsClicked)} - public static func privacyPolicyClicked() -> Verify { return Verify(method: .m_privacyPolicyClicked)} - public static func cookiePolicyClicked() -> Verify { return Verify(method: .m_cookiePolicyClicked)} - public static func emailSupportClicked() -> Verify { return Verify(method: .m_emailSupportClicked)} - public static func faqClicked() -> Verify { return Verify(method: .m_faqClicked)} - public static func tosClicked() -> Verify { return Verify(method: .m_tosClicked)} - public static func dataSellClicked() -> Verify { return Verify(method: .m_dataSellClicked)} - public static func userLogout(force: Parameter) -> Verify { return Verify(method: .m_userLogout__force_force(`force`))} - public static func profileWifiToggle(action: Parameter) -> Verify { return Verify(method: .m_profileWifiToggle__action_action(`action`))} - public static func profileUserDeleteAccountClicked() -> Verify { return Verify(method: .m_profileUserDeleteAccountClicked)} - public static func profileDeleteAccountSuccess(success: Parameter) -> Verify { return Verify(method: .m_profileDeleteAccountSuccess__success_success(`success`))} - public static func profileTrackEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_profileTrackEvent__eventbiValue_biValue(`event`, `biValue`))} - public static func profileScreenEvent(_ event: Parameter, biValue: Parameter) -> Verify { return Verify(method: .m_profileScreenEvent__eventbiValue_biValue(`event`, `biValue`))} + public static func getUserProfile(username: Parameter) -> Verify { return Verify(method: .m_getUserProfile__username_username(`username`))} + public static func getMyProfile() -> Verify { return Verify(method: .m_getMyProfile)} + public static func getMyProfileOffline() -> Verify { return Verify(method: .m_getMyProfileOffline)} + public static func logOut() -> Verify { return Verify(method: .m_logOut)} + public static func getSpokenLanguages() -> Verify { return Verify(method: .m_getSpokenLanguages)} + public static func getCountries() -> Verify { return Verify(method: .m_getCountries)} + public static func uploadProfilePicture(pictureData: Parameter) -> Verify { return Verify(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`))} + public static func deleteProfilePicture() -> Verify { return Verify(method: .m_deleteProfilePicture)} + public static func updateUserProfile(parameters: Parameter<[String: Any]>) -> Verify { return Verify(method: .m_updateUserProfile__parameters_parameters(`parameters`))} + public static func deleteAccount(password: Parameter) -> Verify { return Verify(method: .m_deleteAccount__password_password(`password`))} + public static func getSettings() -> Verify { return Verify(method: .m_getSettings)} + public static func saveSettings(_ settings: Parameter) -> Verify { return Verify(method: .m_saveSettings__settings(`settings`))} + public static func enrollmentsStatus() -> Verify { return Verify(method: .m_enrollmentsStatus)} + public static func getCourseDates(courseID: Parameter) -> Verify { return Verify(method: .m_getCourseDates__courseID_courseID(`courseID`))} } public struct Perform { fileprivate var method: MethodType var performs: Any - public static func profileEditClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_profileEditClicked, performs: perform) - } - public static func profileSwitch(action: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_profileSwitch__action_action(`action`), performs: perform) - } - public static func profileEditDoneClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_profileEditDoneClicked, performs: perform) - } - public static func profileDeleteAccountClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_profileDeleteAccountClicked, performs: perform) + public static func getUserProfile(username: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getUserProfile__username_username(`username`), performs: perform) } - public static func profileVideoSettingsClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_profileVideoSettingsClicked, performs: perform) + public static func getMyProfile(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getMyProfile, performs: perform) } - public static func privacyPolicyClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_privacyPolicyClicked, performs: perform) + public static func getMyProfileOffline(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getMyProfileOffline, performs: perform) } - public static func cookiePolicyClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_cookiePolicyClicked, performs: perform) + public static func logOut(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_logOut, performs: perform) } - public static func emailSupportClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_emailSupportClicked, performs: perform) + public static func getSpokenLanguages(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getSpokenLanguages, performs: perform) } - public static func faqClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_faqClicked, performs: perform) + public static func getCountries(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getCountries, performs: perform) } - public static func tosClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_tosClicked, performs: perform) + public static func uploadProfilePicture(pictureData: Parameter, perform: @escaping (Data) -> Void) -> Perform { + return Perform(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), performs: perform) } - public static func dataSellClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_dataSellClicked, performs: perform) + public static func deleteProfilePicture(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_deleteProfilePicture, performs: perform) } - public static func userLogout(force: Parameter, perform: @escaping (Bool) -> Void) -> Perform { - return Perform(method: .m_userLogout__force_force(`force`), performs: perform) + public static func updateUserProfile(parameters: Parameter<[String: Any]>, perform: @escaping ([String: Any]) -> Void) -> Perform { + return Perform(method: .m_updateUserProfile__parameters_parameters(`parameters`), performs: perform) } - public static func profileWifiToggle(action: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_profileWifiToggle__action_action(`action`), performs: perform) + public static func deleteAccount(password: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_deleteAccount__password_password(`password`), performs: perform) } - public static func profileUserDeleteAccountClicked(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_profileUserDeleteAccountClicked, performs: perform) + public static func getSettings(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getSettings, performs: perform) } - public static func profileDeleteAccountSuccess(success: Parameter, perform: @escaping (Bool) -> Void) -> Perform { - return Perform(method: .m_profileDeleteAccountSuccess__success_success(`success`), performs: perform) + public static func saveSettings(_ settings: Parameter, perform: @escaping (UserSettings) -> Void) -> Perform { + return Perform(method: .m_saveSettings__settings(`settings`), performs: perform) } - public static func profileTrackEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { - return Perform(method: .m_profileTrackEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) + public static func enrollmentsStatus(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_enrollmentsStatus, performs: perform) } - public static func profileScreenEvent(_ event: Parameter, biValue: Parameter, perform: @escaping (AnalyticsEvent, EventBIValue) -> Void) -> Perform { - return Perform(method: .m_profileScreenEvent__eventbiValue_biValue(`event`, `biValue`), performs: perform) + public static func getCourseDates(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getCourseDates__courseID_courseID(`courseID`), performs: perform) } } @@ -3826,9 +5370,9 @@ open class ProfileAnalyticsMock: ProfileAnalytics, Mock { } } -// MARK: - ProfileInteractorProtocol +// MARK: - ProfilePersistenceProtocol -open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { +open class ProfilePersistenceProtocolMock: ProfilePersistenceProtocol, Mock { public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { SwiftyMockyTestObserver.setup() self.sequencingPolicy = sequencingPolicy @@ -3870,268 +5414,131 @@ open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { - open func getUserProfile(username: String) throws -> UserProfile { - addInvocation(.m_getUserProfile__username_username(Parameter.value(`username`))) - let perform = methodPerformValue(.m_getUserProfile__username_username(Parameter.value(`username`))) as? (String) -> Void - perform?(`username`) - var __value: UserProfile - do { - __value = try methodReturnValue(.m_getUserProfile__username_username(Parameter.value(`username`))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for getUserProfile(username: String). Use given") - Failure("Stub return value not specified for getUserProfile(username: String). Use given") - } catch { - throw error - } - return __value - } - - open func getMyProfile() throws -> UserProfile { - addInvocation(.m_getMyProfile) - let perform = methodPerformValue(.m_getMyProfile) as? () -> Void - perform?() - var __value: UserProfile - do { - __value = try methodReturnValue(.m_getMyProfile).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for getMyProfile(). Use given") - Failure("Stub return value not specified for getMyProfile(). Use given") - } catch { - throw error - } - return __value - } - - open func getMyProfileOffline() -> UserProfile? { - addInvocation(.m_getMyProfileOffline) - let perform = methodPerformValue(.m_getMyProfileOffline) as? () -> Void - perform?() - var __value: UserProfile? = nil - do { - __value = try methodReturnValue(.m_getMyProfileOffline).casted() - } catch { - // do nothing - } - return __value - } - - open func logOut() throws { - addInvocation(.m_logOut) - let perform = methodPerformValue(.m_logOut) as? () -> Void - perform?() - do { - _ = try methodReturnValue(.m_logOut).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } - } - - open func getSpokenLanguages() -> [PickerFields.Option] { - addInvocation(.m_getSpokenLanguages) - let perform = methodPerformValue(.m_getSpokenLanguages) as? () -> Void - perform?() - var __value: [PickerFields.Option] - do { - __value = try methodReturnValue(.m_getSpokenLanguages).casted() - } catch { - onFatalFailure("Stub return value not specified for getSpokenLanguages(). Use given") - Failure("Stub return value not specified for getSpokenLanguages(). Use given") - } - return __value - } - - open func getCountries() -> [PickerFields.Option] { - addInvocation(.m_getCountries) - let perform = methodPerformValue(.m_getCountries) as? () -> Void - perform?() - var __value: [PickerFields.Option] - do { - __value = try methodReturnValue(.m_getCountries).casted() - } catch { - onFatalFailure("Stub return value not specified for getCountries(). Use given") - Failure("Stub return value not specified for getCountries(). Use given") - } - return __value - } - - open func uploadProfilePicture(pictureData: Data) throws { - addInvocation(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))) - let perform = methodPerformValue(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))) as? (Data) -> Void - perform?(`pictureData`) - do { - _ = try methodReturnValue(.m_uploadProfilePicture__pictureData_pictureData(Parameter.value(`pictureData`))).casted() as Void - } catch MockError.notStubed { - // do nothing - } catch { - throw error - } - } - - open func deleteProfilePicture() throws -> Bool { - addInvocation(.m_deleteProfilePicture) - let perform = methodPerformValue(.m_deleteProfilePicture) as? () -> Void - perform?() - var __value: Bool - do { - __value = try methodReturnValue(.m_deleteProfilePicture).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for deleteProfilePicture(). Use given") - Failure("Stub return value not specified for deleteProfilePicture(). Use given") - } catch { - throw error - } - return __value - } - - open func updateUserProfile(parameters: [String: Any]) throws -> UserProfile { - addInvocation(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))) - let perform = methodPerformValue(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))) as? ([String: Any]) -> Void - perform?(`parameters`) - var __value: UserProfile - do { - __value = try methodReturnValue(.m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>.value(`parameters`))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for updateUserProfile(parameters: [String: Any]). Use given") - Failure("Stub return value not specified for updateUserProfile(parameters: [String: Any]). Use given") - } catch { - throw error - } - return __value - } - - open func deleteAccount(password: String) throws -> Bool { - addInvocation(.m_deleteAccount__password_password(Parameter.value(`password`))) - let perform = methodPerformValue(.m_deleteAccount__password_password(Parameter.value(`password`))) as? (String) -> Void - perform?(`password`) - var __value: Bool + open func getCourseState(courseID: String) -> CourseCalendarState? { + addInvocation(.m_getCourseState__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_getCourseState__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + var __value: CourseCalendarState? = nil do { - __value = try methodReturnValue(.m_deleteAccount__password_password(Parameter.value(`password`))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for deleteAccount(password: String). Use given") - Failure("Stub return value not specified for deleteAccount(password: String). Use given") + __value = try methodReturnValue(.m_getCourseState__courseID_courseID(Parameter.value(`courseID`))).casted() } catch { - throw error + // do nothing } return __value } - open func getSettings() -> UserSettings { - addInvocation(.m_getSettings) - let perform = methodPerformValue(.m_getSettings) as? () -> Void + open func getAllCourseStates() -> [CourseCalendarState] { + addInvocation(.m_getAllCourseStates) + let perform = methodPerformValue(.m_getAllCourseStates) as? () -> Void perform?() - var __value: UserSettings + var __value: [CourseCalendarState] do { - __value = try methodReturnValue(.m_getSettings).casted() + __value = try methodReturnValue(.m_getAllCourseStates).casted() } catch { - onFatalFailure("Stub return value not specified for getSettings(). Use given") - Failure("Stub return value not specified for getSettings(). Use given") + onFatalFailure("Stub return value not specified for getAllCourseStates(). Use given") + Failure("Stub return value not specified for getAllCourseStates(). Use given") } return __value } - open func saveSettings(_ settings: UserSettings) { - addInvocation(.m_saveSettings__settings(Parameter.value(`settings`))) - let perform = methodPerformValue(.m_saveSettings__settings(Parameter.value(`settings`))) as? (UserSettings) -> Void - perform?(`settings`) + open func saveCourseState(state: CourseCalendarState) { + addInvocation(.m_saveCourseState__state_state(Parameter.value(`state`))) + let perform = methodPerformValue(.m_saveCourseState__state_state(Parameter.value(`state`))) as? (CourseCalendarState) -> Void + perform?(`state`) } - open func enrollmentsStatus() throws -> [CourseForSync] { - addInvocation(.m_enrollmentsStatus) - let perform = methodPerformValue(.m_enrollmentsStatus) as? () -> Void + open func removeCourseState(courseID: String) { + addInvocation(.m_removeCourseState__courseID_courseID(Parameter.value(`courseID`))) + let perform = methodPerformValue(.m_removeCourseState__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void + perform?(`courseID`) + } + + open func deleteAllCourseStatesAndEvents() { + addInvocation(.m_deleteAllCourseStatesAndEvents) + let perform = methodPerformValue(.m_deleteAllCourseStatesAndEvents) as? () -> Void perform?() - var __value: [CourseForSync] - do { - __value = try methodReturnValue(.m_enrollmentsStatus).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for enrollmentsStatus(). Use given") - Failure("Stub return value not specified for enrollmentsStatus(). Use given") - } catch { - throw error - } - return __value } - open func getCourseDates(courseID: String) throws -> CourseDates { - addInvocation(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))) - let perform = methodPerformValue(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))) as? (String) -> Void - perform?(`courseID`) - var __value: CourseDates + open func saveCourseCalendarEvent(_ event: CourseCalendarEvent) { + addInvocation(.m_saveCourseCalendarEvent__event(Parameter.value(`event`))) + let perform = methodPerformValue(.m_saveCourseCalendarEvent__event(Parameter.value(`event`))) as? (CourseCalendarEvent) -> Void + perform?(`event`) + } + + open func removeCourseCalendarEvents(for courseId: String) { + addInvocation(.m_removeCourseCalendarEvents__for_courseId(Parameter.value(`courseId`))) + let perform = methodPerformValue(.m_removeCourseCalendarEvents__for_courseId(Parameter.value(`courseId`))) as? (String) -> Void + perform?(`courseId`) + } + + open func removeAllCourseCalendarEvents() { + addInvocation(.m_removeAllCourseCalendarEvents) + let perform = methodPerformValue(.m_removeAllCourseCalendarEvents) as? () -> Void + perform?() + } + + open func getCourseCalendarEvents(for courseId: String) -> [CourseCalendarEvent] { + addInvocation(.m_getCourseCalendarEvents__for_courseId(Parameter.value(`courseId`))) + let perform = methodPerformValue(.m_getCourseCalendarEvents__for_courseId(Parameter.value(`courseId`))) as? (String) -> Void + perform?(`courseId`) + var __value: [CourseCalendarEvent] do { - __value = try methodReturnValue(.m_getCourseDates__courseID_courseID(Parameter.value(`courseID`))).casted() - } catch MockError.notStubed { - onFatalFailure("Stub return value not specified for getCourseDates(courseID: String). Use given") - Failure("Stub return value not specified for getCourseDates(courseID: String). Use given") + __value = try methodReturnValue(.m_getCourseCalendarEvents__for_courseId(Parameter.value(`courseId`))).casted() } catch { - throw error + onFatalFailure("Stub return value not specified for getCourseCalendarEvents(for courseId: String). Use given") + Failure("Stub return value not specified for getCourseCalendarEvents(for courseId: String). Use given") } return __value } fileprivate enum MethodType { - case m_getUserProfile__username_username(Parameter) - case m_getMyProfile - case m_getMyProfileOffline - case m_logOut - case m_getSpokenLanguages - case m_getCountries - case m_uploadProfilePicture__pictureData_pictureData(Parameter) - case m_deleteProfilePicture - case m_updateUserProfile__parameters_parameters(Parameter<[String: Any]>) - case m_deleteAccount__password_password(Parameter) - case m_getSettings - case m_saveSettings__settings(Parameter) - case m_enrollmentsStatus - case m_getCourseDates__courseID_courseID(Parameter) + case m_getCourseState__courseID_courseID(Parameter) + case m_getAllCourseStates + case m_saveCourseState__state_state(Parameter) + case m_removeCourseState__courseID_courseID(Parameter) + case m_deleteAllCourseStatesAndEvents + case m_saveCourseCalendarEvent__event(Parameter) + case m_removeCourseCalendarEvents__for_courseId(Parameter) + case m_removeAllCourseCalendarEvents + case m_getCourseCalendarEvents__for_courseId(Parameter) static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { switch (lhs, rhs) { - case (.m_getUserProfile__username_username(let lhsUsername), .m_getUserProfile__username_username(let rhsUsername)): + case (.m_getCourseState__courseID_courseID(let lhsCourseid), .m_getCourseState__courseID_courseID(let rhsCourseid)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsUsername, rhs: rhsUsername, with: matcher), lhsUsername, rhsUsername, "username")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) return Matcher.ComparisonResult(results) - case (.m_getMyProfile, .m_getMyProfile): return .match - - case (.m_getMyProfileOffline, .m_getMyProfileOffline): return .match - - case (.m_logOut, .m_logOut): return .match - - case (.m_getSpokenLanguages, .m_getSpokenLanguages): return .match - - case (.m_getCountries, .m_getCountries): return .match + case (.m_getAllCourseStates, .m_getAllCourseStates): return .match - case (.m_uploadProfilePicture__pictureData_pictureData(let lhsPicturedata), .m_uploadProfilePicture__pictureData_pictureData(let rhsPicturedata)): + case (.m_saveCourseState__state_state(let lhsState), .m_saveCourseState__state_state(let rhsState)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsPicturedata, rhs: rhsPicturedata, with: matcher), lhsPicturedata, rhsPicturedata, "pictureData")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsState, rhs: rhsState, with: matcher), lhsState, rhsState, "state")) return Matcher.ComparisonResult(results) - case (.m_deleteProfilePicture, .m_deleteProfilePicture): return .match - - case (.m_updateUserProfile__parameters_parameters(let lhsParameters), .m_updateUserProfile__parameters_parameters(let rhsParameters)): + case (.m_removeCourseState__courseID_courseID(let lhsCourseid), .m_removeCourseState__courseID_courseID(let rhsCourseid)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsParameters, rhs: rhsParameters, with: matcher), lhsParameters, rhsParameters, "parameters")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) return Matcher.ComparisonResult(results) - case (.m_deleteAccount__password_password(let lhsPassword), .m_deleteAccount__password_password(let rhsPassword)): + case (.m_deleteAllCourseStatesAndEvents, .m_deleteAllCourseStatesAndEvents): return .match + + case (.m_saveCourseCalendarEvent__event(let lhsEvent), .m_saveCourseCalendarEvent__event(let rhsEvent)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsPassword, rhs: rhsPassword, with: matcher), lhsPassword, rhsPassword, "password")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsEvent, rhs: rhsEvent, with: matcher), lhsEvent, rhsEvent, "_ event")) return Matcher.ComparisonResult(results) - case (.m_getSettings, .m_getSettings): return .match - - case (.m_saveSettings__settings(let lhsSettings), .m_saveSettings__settings(let rhsSettings)): + case (.m_removeCourseCalendarEvents__for_courseId(let lhsCourseid), .m_removeCourseCalendarEvents__for_courseId(let rhsCourseid)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsSettings, rhs: rhsSettings, with: matcher), lhsSettings, rhsSettings, "_ settings")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "for courseId")) return Matcher.ComparisonResult(results) - case (.m_enrollmentsStatus, .m_enrollmentsStatus): return .match + case (.m_removeAllCourseCalendarEvents, .m_removeAllCourseCalendarEvents): return .match - case (.m_getCourseDates__courseID_courseID(let lhsCourseid), .m_getCourseDates__courseID_courseID(let rhsCourseid)): + case (.m_getCourseCalendarEvents__for_courseId(let lhsCourseid), .m_getCourseCalendarEvents__for_courseId(let rhsCourseid)): var results: [Matcher.ParameterComparisonResult] = [] - results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "courseID")) + results.append(Matcher.ParameterComparisonResult(Parameter.compare(lhs: lhsCourseid, rhs: rhsCourseid, with: matcher), lhsCourseid, rhsCourseid, "for courseId")) return Matcher.ComparisonResult(results) default: return .none } @@ -4139,38 +5546,28 @@ open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { func intValue() -> Int { switch self { - case let .m_getUserProfile__username_username(p0): return p0.intValue - case .m_getMyProfile: return 0 - case .m_getMyProfileOffline: return 0 - case .m_logOut: return 0 - case .m_getSpokenLanguages: return 0 - case .m_getCountries: return 0 - case let .m_uploadProfilePicture__pictureData_pictureData(p0): return p0.intValue - case .m_deleteProfilePicture: return 0 - case let .m_updateUserProfile__parameters_parameters(p0): return p0.intValue - case let .m_deleteAccount__password_password(p0): return p0.intValue - case .m_getSettings: return 0 - case let .m_saveSettings__settings(p0): return p0.intValue - case .m_enrollmentsStatus: return 0 - case let .m_getCourseDates__courseID_courseID(p0): return p0.intValue + case let .m_getCourseState__courseID_courseID(p0): return p0.intValue + case .m_getAllCourseStates: return 0 + case let .m_saveCourseState__state_state(p0): return p0.intValue + case let .m_removeCourseState__courseID_courseID(p0): return p0.intValue + case .m_deleteAllCourseStatesAndEvents: return 0 + case let .m_saveCourseCalendarEvent__event(p0): return p0.intValue + case let .m_removeCourseCalendarEvents__for_courseId(p0): return p0.intValue + case .m_removeAllCourseCalendarEvents: return 0 + case let .m_getCourseCalendarEvents__for_courseId(p0): return p0.intValue } } func assertionName() -> String { switch self { - case .m_getUserProfile__username_username: return ".getUserProfile(username:)" - case .m_getMyProfile: return ".getMyProfile()" - case .m_getMyProfileOffline: return ".getMyProfileOffline()" - case .m_logOut: return ".logOut()" - case .m_getSpokenLanguages: return ".getSpokenLanguages()" - case .m_getCountries: return ".getCountries()" - case .m_uploadProfilePicture__pictureData_pictureData: return ".uploadProfilePicture(pictureData:)" - case .m_deleteProfilePicture: return ".deleteProfilePicture()" - case .m_updateUserProfile__parameters_parameters: return ".updateUserProfile(parameters:)" - case .m_deleteAccount__password_password: return ".deleteAccount(password:)" - case .m_getSettings: return ".getSettings()" - case .m_saveSettings__settings: return ".saveSettings(_:)" - case .m_enrollmentsStatus: return ".enrollmentsStatus()" - case .m_getCourseDates__courseID_courseID: return ".getCourseDates(courseID:)" + case .m_getCourseState__courseID_courseID: return ".getCourseState(courseID:)" + case .m_getAllCourseStates: return ".getAllCourseStates()" + case .m_saveCourseState__state_state: return ".saveCourseState(state:)" + case .m_removeCourseState__courseID_courseID: return ".removeCourseState(courseID:)" + case .m_deleteAllCourseStatesAndEvents: return ".deleteAllCourseStatesAndEvents()" + case .m_saveCourseCalendarEvent__event: return ".saveCourseCalendarEvent(_:)" + case .m_removeCourseCalendarEvents__for_courseId: return ".removeCourseCalendarEvents(for:)" + case .m_removeAllCourseCalendarEvents: return ".removeAllCourseCalendarEvents()" + case .m_getCourseCalendarEvents__for_courseId: return ".getCourseCalendarEvents(for:)" } } } @@ -4184,154 +5581,33 @@ open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { } - public static func getUserProfile(username: Parameter, willReturn: UserProfile...) -> MethodStub { - return Given(method: .m_getUserProfile__username_username(`username`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getMyProfile(willReturn: UserProfile...) -> MethodStub { - return Given(method: .m_getMyProfile, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getMyProfileOffline(willReturn: UserProfile?...) -> MethodStub { - return Given(method: .m_getMyProfileOffline, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getSpokenLanguages(willReturn: [PickerFields.Option]...) -> MethodStub { - return Given(method: .m_getSpokenLanguages, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getCountries(willReturn: [PickerFields.Option]...) -> MethodStub { - return Given(method: .m_getCountries, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func deleteProfilePicture(willReturn: Bool...) -> MethodStub { - return Given(method: .m_deleteProfilePicture, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func updateUserProfile(parameters: Parameter<[String: Any]>, willReturn: UserProfile...) -> MethodStub { - return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func deleteAccount(password: Parameter, willReturn: Bool...) -> MethodStub { - return Given(method: .m_deleteAccount__password_password(`password`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getSettings(willReturn: UserSettings...) -> MethodStub { - return Given(method: .m_getSettings, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func enrollmentsStatus(willReturn: [CourseForSync]...) -> MethodStub { - return Given(method: .m_enrollmentsStatus, products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getCourseDates(courseID: Parameter, willReturn: CourseDates...) -> MethodStub { - return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) - } - public static func getMyProfileOffline(willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [UserProfile?] = [] - let given: Given = { return Given(method: .m_getMyProfileOffline, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (UserProfile?).self) - willProduce(stubber) - return given - } - public static func getSpokenLanguages(willProduce: (Stubber<[PickerFields.Option]>) -> Void) -> MethodStub { - let willReturn: [[PickerFields.Option]] = [] - let given: Given = { return Given(method: .m_getSpokenLanguages, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([PickerFields.Option]).self) - willProduce(stubber) - return given - } - public static func getCountries(willProduce: (Stubber<[PickerFields.Option]>) -> Void) -> MethodStub { - let willReturn: [[PickerFields.Option]] = [] - let given: Given = { return Given(method: .m_getCountries, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: ([PickerFields.Option]).self) - willProduce(stubber) - return given - } - public static func getSettings(willProduce: (Stubber) -> Void) -> MethodStub { - let willReturn: [UserSettings] = [] - let given: Given = { return Given(method: .m_getSettings, products: willReturn.map({ StubProduct.return($0 as Any) })) }() - let stubber = given.stub(for: (UserSettings).self) - willProduce(stubber) - return given - } - public static func getUserProfile(username: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_getUserProfile__username_username(`username`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func getUserProfile(username: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_getUserProfile__username_username(`username`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (UserProfile).self) - willProduce(stubber) - return given - } - public static func getMyProfile(willThrow: Error...) -> MethodStub { - return Given(method: .m_getMyProfile, products: willThrow.map({ StubProduct.throw($0) })) - } - public static func getMyProfile(willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_getMyProfile, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (UserProfile).self) - willProduce(stubber) - return given - } - public static func logOut(willThrow: Error...) -> MethodStub { - return Given(method: .m_logOut, products: willThrow.map({ StubProduct.throw($0) })) - } - public static func logOut(willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_logOut, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - public static func uploadProfilePicture(pictureData: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func uploadProfilePicture(pictureData: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Void).self) - willProduce(stubber) - return given - } - public static func deleteProfilePicture(willThrow: Error...) -> MethodStub { - return Given(method: .m_deleteProfilePicture, products: willThrow.map({ StubProduct.throw($0) })) - } - public static func deleteProfilePicture(willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_deleteProfilePicture, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Bool).self) - willProduce(stubber) - return given - } - public static func updateUserProfile(parameters: Parameter<[String: Any]>, willThrow: Error...) -> MethodStub { - return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func updateUserProfile(parameters: Parameter<[String: Any]>, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_updateUserProfile__parameters_parameters(`parameters`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (UserProfile).self) - willProduce(stubber) - return given - } - public static func deleteAccount(password: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_deleteAccount__password_password(`password`), products: willThrow.map({ StubProduct.throw($0) })) - } - public static func deleteAccount(password: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_deleteAccount__password_password(`password`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (Bool).self) - willProduce(stubber) - return given + public static func getCourseState(courseID: Parameter, willReturn: CourseCalendarState?...) -> MethodStub { + return Given(method: .m_getCourseState__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) } - public static func enrollmentsStatus(willThrow: Error...) -> MethodStub { - return Given(method: .m_enrollmentsStatus, products: willThrow.map({ StubProduct.throw($0) })) + public static func getAllCourseStates(willReturn: [CourseCalendarState]...) -> MethodStub { + return Given(method: .m_getAllCourseStates, products: willReturn.map({ StubProduct.return($0 as Any) })) } - public static func enrollmentsStatus(willProduce: (StubberThrows<[CourseForSync]>) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_enrollmentsStatus, products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: ([CourseForSync]).self) + public static func getCourseCalendarEvents(for courseId: Parameter, willReturn: [CourseCalendarEvent]...) -> MethodStub { + return Given(method: .m_getCourseCalendarEvents__for_courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) + } + public static func getCourseState(courseID: Parameter, willProduce: (Stubber) -> Void) -> MethodStub { + let willReturn: [CourseCalendarState?] = [] + let given: Given = { return Given(method: .m_getCourseState__courseID_courseID(`courseID`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: (CourseCalendarState?).self) willProduce(stubber) return given } - public static func getCourseDates(courseID: Parameter, willThrow: Error...) -> MethodStub { - return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willThrow.map({ StubProduct.throw($0) })) + public static func getAllCourseStates(willProduce: (Stubber<[CourseCalendarState]>) -> Void) -> MethodStub { + let willReturn: [[CourseCalendarState]] = [] + let given: Given = { return Given(method: .m_getAllCourseStates, products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseCalendarState]).self) + willProduce(stubber) + return given } - public static func getCourseDates(courseID: Parameter, willProduce: (StubberThrows) -> Void) -> MethodStub { - let willThrow: [Error] = [] - let given: Given = { return Given(method: .m_getCourseDates__courseID_courseID(`courseID`), products: willThrow.map({ StubProduct.throw($0) })) }() - let stubber = given.stubThrows(for: (CourseDates).self) + public static func getCourseCalendarEvents(for courseId: Parameter, willProduce: (Stubber<[CourseCalendarEvent]>) -> Void) -> MethodStub { + let willReturn: [[CourseCalendarEvent]] = [] + let given: Given = { return Given(method: .m_getCourseCalendarEvents__for_courseId(`courseId`), products: willReturn.map({ StubProduct.return($0 as Any) })) }() + let stubber = given.stub(for: ([CourseCalendarEvent]).self) willProduce(stubber) return given } @@ -4340,67 +5616,47 @@ open class ProfileInteractorProtocolMock: ProfileInteractorProtocol, Mock { public struct Verify { fileprivate var method: MethodType - public static func getUserProfile(username: Parameter) -> Verify { return Verify(method: .m_getUserProfile__username_username(`username`))} - public static func getMyProfile() -> Verify { return Verify(method: .m_getMyProfile)} - public static func getMyProfileOffline() -> Verify { return Verify(method: .m_getMyProfileOffline)} - public static func logOut() -> Verify { return Verify(method: .m_logOut)} - public static func getSpokenLanguages() -> Verify { return Verify(method: .m_getSpokenLanguages)} - public static func getCountries() -> Verify { return Verify(method: .m_getCountries)} - public static func uploadProfilePicture(pictureData: Parameter) -> Verify { return Verify(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`))} - public static func deleteProfilePicture() -> Verify { return Verify(method: .m_deleteProfilePicture)} - public static func updateUserProfile(parameters: Parameter<[String: Any]>) -> Verify { return Verify(method: .m_updateUserProfile__parameters_parameters(`parameters`))} - public static func deleteAccount(password: Parameter) -> Verify { return Verify(method: .m_deleteAccount__password_password(`password`))} - public static func getSettings() -> Verify { return Verify(method: .m_getSettings)} - public static func saveSettings(_ settings: Parameter) -> Verify { return Verify(method: .m_saveSettings__settings(`settings`))} - public static func enrollmentsStatus() -> Verify { return Verify(method: .m_enrollmentsStatus)} - public static func getCourseDates(courseID: Parameter) -> Verify { return Verify(method: .m_getCourseDates__courseID_courseID(`courseID`))} + public static func getCourseState(courseID: Parameter) -> Verify { return Verify(method: .m_getCourseState__courseID_courseID(`courseID`))} + public static func getAllCourseStates() -> Verify { return Verify(method: .m_getAllCourseStates)} + public static func saveCourseState(state: Parameter) -> Verify { return Verify(method: .m_saveCourseState__state_state(`state`))} + public static func removeCourseState(courseID: Parameter) -> Verify { return Verify(method: .m_removeCourseState__courseID_courseID(`courseID`))} + public static func deleteAllCourseStatesAndEvents() -> Verify { return Verify(method: .m_deleteAllCourseStatesAndEvents)} + public static func saveCourseCalendarEvent(_ event: Parameter) -> Verify { return Verify(method: .m_saveCourseCalendarEvent__event(`event`))} + public static func removeCourseCalendarEvents(for courseId: Parameter) -> Verify { return Verify(method: .m_removeCourseCalendarEvents__for_courseId(`courseId`))} + public static func removeAllCourseCalendarEvents() -> Verify { return Verify(method: .m_removeAllCourseCalendarEvents)} + public static func getCourseCalendarEvents(for courseId: Parameter) -> Verify { return Verify(method: .m_getCourseCalendarEvents__for_courseId(`courseId`))} } public struct Perform { fileprivate var method: MethodType var performs: Any - public static func getUserProfile(username: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_getUserProfile__username_username(`username`), performs: perform) - } - public static func getMyProfile(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getMyProfile, performs: perform) - } - public static func getMyProfileOffline(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getMyProfileOffline, performs: perform) - } - public static func logOut(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_logOut, performs: perform) + public static func getCourseState(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getCourseState__courseID_courseID(`courseID`), performs: perform) } - public static func getSpokenLanguages(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getSpokenLanguages, performs: perform) - } - public static func getCountries(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getCountries, performs: perform) - } - public static func uploadProfilePicture(pictureData: Parameter, perform: @escaping (Data) -> Void) -> Perform { - return Perform(method: .m_uploadProfilePicture__pictureData_pictureData(`pictureData`), performs: perform) + public static func getAllCourseStates(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_getAllCourseStates, performs: perform) } - public static func deleteProfilePicture(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_deleteProfilePicture, performs: perform) + public static func saveCourseState(state: Parameter, perform: @escaping (CourseCalendarState) -> Void) -> Perform { + return Perform(method: .m_saveCourseState__state_state(`state`), performs: perform) } - public static func updateUserProfile(parameters: Parameter<[String: Any]>, perform: @escaping ([String: Any]) -> Void) -> Perform { - return Perform(method: .m_updateUserProfile__parameters_parameters(`parameters`), performs: perform) + public static func removeCourseState(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeCourseState__courseID_courseID(`courseID`), performs: perform) } - public static func deleteAccount(password: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_deleteAccount__password_password(`password`), performs: perform) + public static func deleteAllCourseStatesAndEvents(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_deleteAllCourseStatesAndEvents, performs: perform) } - public static func getSettings(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_getSettings, performs: perform) + public static func saveCourseCalendarEvent(_ event: Parameter, perform: @escaping (CourseCalendarEvent) -> Void) -> Perform { + return Perform(method: .m_saveCourseCalendarEvent__event(`event`), performs: perform) } - public static func saveSettings(_ settings: Parameter, perform: @escaping (UserSettings) -> Void) -> Perform { - return Perform(method: .m_saveSettings__settings(`settings`), performs: perform) + public static func removeCourseCalendarEvents(for courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_removeCourseCalendarEvents__for_courseId(`courseId`), performs: perform) } - public static func enrollmentsStatus(perform: @escaping () -> Void) -> Perform { - return Perform(method: .m_enrollmentsStatus, performs: perform) + public static func removeAllCourseCalendarEvents(perform: @escaping () -> Void) -> Perform { + return Perform(method: .m_removeAllCourseCalendarEvents, performs: perform) } - public static func getCourseDates(courseID: Parameter, perform: @escaping (String) -> Void) -> Perform { - return Perform(method: .m_getCourseDates__courseID_courseID(`courseID`), performs: perform) + public static func getCourseCalendarEvents(for courseId: Parameter, perform: @escaping (String) -> Void) -> Perform { + return Perform(method: .m_getCourseCalendarEvents__for_courseId(`courseId`), performs: perform) } } @@ -5112,6 +6368,315 @@ open class ProfileRouterMock: ProfileRouter, Mock { } } +// MARK: - ProfileStorage + +open class ProfileStorageMock: ProfileStorage, Mock { + public init(sequencing sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst, stubbing stubbingPolicy: StubbingPolicy = .wrap, file: StaticString = #file, line: UInt = #line) { + SwiftyMockyTestObserver.setup() + self.sequencingPolicy = sequencingPolicy + self.stubbingPolicy = stubbingPolicy + self.file = file + self.line = line + } + + var matcher: Matcher = Matcher.default + var stubbingPolicy: StubbingPolicy = .wrap + var sequencingPolicy: SequencingPolicy = .lastWrittenResolvedFirst + + private var queue = DispatchQueue(label: "com.swiftymocky.invocations", qos: .userInteractive) + private var invocations: [MethodType] = [] + private var methodReturnValues: [Given] = [] + private var methodPerformValues: [Perform] = [] + private var file: StaticString? + private var line: UInt? + + public typealias PropertyStub = Given + public typealias MethodStub = Given + public typealias SubscriptStub = Given + + /// Convenience method - call setupMock() to extend debug information when failure occurs + public func setupMock(file: StaticString = #file, line: UInt = #line) { + self.file = file + self.line = line + } + + /// Clear mock internals. You can specify what to reset (invocations aka verify, givens or performs) or leave it empty to clear all mock internals + public func resetMock(_ scopes: MockScope...) { + let scopes: [MockScope] = scopes.isEmpty ? [.invocation, .given, .perform] : scopes + if scopes.contains(.invocation) { invocations = [] } + if scopes.contains(.given) { methodReturnValues = [] } + if scopes.contains(.perform) { methodPerformValues = [] } + } + + public var userProfile: DataLayer.UserProfile? { + get { invocations.append(.p_userProfile_get); return __p_userProfile ?? optionalGivenGetterValue(.p_userProfile_get, "ProfileStorageMock - stub value for userProfile was not defined") } + set { invocations.append(.p_userProfile_set(.value(newValue))); __p_userProfile = newValue } + } + private var __p_userProfile: (DataLayer.UserProfile)? + + public var useRelativeDates: Bool { + get { invocations.append(.p_useRelativeDates_get); return __p_useRelativeDates ?? givenGetterValue(.p_useRelativeDates_get, "ProfileStorageMock - stub value for useRelativeDates was not defined") } + set { invocations.append(.p_useRelativeDates_set(.value(newValue))); __p_useRelativeDates = newValue } + } + private var __p_useRelativeDates: (Bool)? + + public var calendarSettings: CalendarSettings? { + get { invocations.append(.p_calendarSettings_get); return __p_calendarSettings ?? optionalGivenGetterValue(.p_calendarSettings_get, "ProfileStorageMock - stub value for calendarSettings was not defined") } + set { invocations.append(.p_calendarSettings_set(.value(newValue))); __p_calendarSettings = newValue } + } + private var __p_calendarSettings: (CalendarSettings)? + + public var hideInactiveCourses: Bool? { + get { invocations.append(.p_hideInactiveCourses_get); return __p_hideInactiveCourses ?? optionalGivenGetterValue(.p_hideInactiveCourses_get, "ProfileStorageMock - stub value for hideInactiveCourses was not defined") } + set { invocations.append(.p_hideInactiveCourses_set(.value(newValue))); __p_hideInactiveCourses = newValue } + } + private var __p_hideInactiveCourses: (Bool)? + + public var lastLoginUsername: String? { + get { invocations.append(.p_lastLoginUsername_get); return __p_lastLoginUsername ?? optionalGivenGetterValue(.p_lastLoginUsername_get, "ProfileStorageMock - stub value for lastLoginUsername was not defined") } + set { invocations.append(.p_lastLoginUsername_set(.value(newValue))); __p_lastLoginUsername = newValue } + } + private var __p_lastLoginUsername: (String)? + + public var lastCalendarName: String? { + get { invocations.append(.p_lastCalendarName_get); return __p_lastCalendarName ?? optionalGivenGetterValue(.p_lastCalendarName_get, "ProfileStorageMock - stub value for lastCalendarName was not defined") } + set { invocations.append(.p_lastCalendarName_set(.value(newValue))); __p_lastCalendarName = newValue } + } + private var __p_lastCalendarName: (String)? + + public var lastCalendarUpdateDate: Date? { + get { invocations.append(.p_lastCalendarUpdateDate_get); return __p_lastCalendarUpdateDate ?? optionalGivenGetterValue(.p_lastCalendarUpdateDate_get, "ProfileStorageMock - stub value for lastCalendarUpdateDate was not defined") } + set { invocations.append(.p_lastCalendarUpdateDate_set(.value(newValue))); __p_lastCalendarUpdateDate = newValue } + } + private var __p_lastCalendarUpdateDate: (Date)? + + public var firstCalendarUpdate: Bool? { + get { invocations.append(.p_firstCalendarUpdate_get); return __p_firstCalendarUpdate ?? optionalGivenGetterValue(.p_firstCalendarUpdate_get, "ProfileStorageMock - stub value for firstCalendarUpdate was not defined") } + set { invocations.append(.p_firstCalendarUpdate_set(.value(newValue))); __p_firstCalendarUpdate = newValue } + } + private var __p_firstCalendarUpdate: (Bool)? + + + + + + + fileprivate enum MethodType { + case p_userProfile_get + case p_userProfile_set(Parameter) + case p_useRelativeDates_get + case p_useRelativeDates_set(Parameter) + case p_calendarSettings_get + case p_calendarSettings_set(Parameter) + case p_hideInactiveCourses_get + case p_hideInactiveCourses_set(Parameter) + case p_lastLoginUsername_get + case p_lastLoginUsername_set(Parameter) + case p_lastCalendarName_get + case p_lastCalendarName_set(Parameter) + case p_lastCalendarUpdateDate_get + case p_lastCalendarUpdateDate_set(Parameter) + case p_firstCalendarUpdate_get + case p_firstCalendarUpdate_set(Parameter) + + static func compareParameters(lhs: MethodType, rhs: MethodType, matcher: Matcher) -> Matcher.ComparisonResult { + switch (lhs, rhs) { case (.p_userProfile_get,.p_userProfile_get): return Matcher.ComparisonResult.match + case (.p_userProfile_set(let left),.p_userProfile_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_useRelativeDates_get,.p_useRelativeDates_get): return Matcher.ComparisonResult.match + case (.p_useRelativeDates_set(let left),.p_useRelativeDates_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_calendarSettings_get,.p_calendarSettings_get): return Matcher.ComparisonResult.match + case (.p_calendarSettings_set(let left),.p_calendarSettings_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_hideInactiveCourses_get,.p_hideInactiveCourses_get): return Matcher.ComparisonResult.match + case (.p_hideInactiveCourses_set(let left),.p_hideInactiveCourses_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_lastLoginUsername_get,.p_lastLoginUsername_get): return Matcher.ComparisonResult.match + case (.p_lastLoginUsername_set(let left),.p_lastLoginUsername_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_lastCalendarName_get,.p_lastCalendarName_get): return Matcher.ComparisonResult.match + case (.p_lastCalendarName_set(let left),.p_lastCalendarName_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_lastCalendarUpdateDate_get,.p_lastCalendarUpdateDate_get): return Matcher.ComparisonResult.match + case (.p_lastCalendarUpdateDate_set(let left),.p_lastCalendarUpdateDate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + case (.p_firstCalendarUpdate_get,.p_firstCalendarUpdate_get): return Matcher.ComparisonResult.match + case (.p_firstCalendarUpdate_set(let left),.p_firstCalendarUpdate_set(let right)): return Matcher.ComparisonResult([Matcher.ParameterComparisonResult(Parameter.compare(lhs: left, rhs: right, with: matcher), left, right, "newValue")]) + default: return .none + } + } + + func intValue() -> Int { + switch self { + case .p_userProfile_get: return 0 + case .p_userProfile_set(let newValue): return newValue.intValue + case .p_useRelativeDates_get: return 0 + case .p_useRelativeDates_set(let newValue): return newValue.intValue + case .p_calendarSettings_get: return 0 + case .p_calendarSettings_set(let newValue): return newValue.intValue + case .p_hideInactiveCourses_get: return 0 + case .p_hideInactiveCourses_set(let newValue): return newValue.intValue + case .p_lastLoginUsername_get: return 0 + case .p_lastLoginUsername_set(let newValue): return newValue.intValue + case .p_lastCalendarName_get: return 0 + case .p_lastCalendarName_set(let newValue): return newValue.intValue + case .p_lastCalendarUpdateDate_get: return 0 + case .p_lastCalendarUpdateDate_set(let newValue): return newValue.intValue + case .p_firstCalendarUpdate_get: return 0 + case .p_firstCalendarUpdate_set(let newValue): return newValue.intValue + } + } + func assertionName() -> String { + switch self { + case .p_userProfile_get: return "[get] .userProfile" + case .p_userProfile_set: return "[set] .userProfile" + case .p_useRelativeDates_get: return "[get] .useRelativeDates" + case .p_useRelativeDates_set: return "[set] .useRelativeDates" + case .p_calendarSettings_get: return "[get] .calendarSettings" + case .p_calendarSettings_set: return "[set] .calendarSettings" + case .p_hideInactiveCourses_get: return "[get] .hideInactiveCourses" + case .p_hideInactiveCourses_set: return "[set] .hideInactiveCourses" + case .p_lastLoginUsername_get: return "[get] .lastLoginUsername" + case .p_lastLoginUsername_set: return "[set] .lastLoginUsername" + case .p_lastCalendarName_get: return "[get] .lastCalendarName" + case .p_lastCalendarName_set: return "[set] .lastCalendarName" + case .p_lastCalendarUpdateDate_get: return "[get] .lastCalendarUpdateDate" + case .p_lastCalendarUpdateDate_set: return "[set] .lastCalendarUpdateDate" + case .p_firstCalendarUpdate_get: return "[get] .firstCalendarUpdate" + case .p_firstCalendarUpdate_set: return "[set] .firstCalendarUpdate" + } + } + } + + open class Given: StubbedMethod { + fileprivate var method: MethodType + + private init(method: MethodType, products: [StubProduct]) { + self.method = method + super.init(products) + } + + public static func userProfile(getter defaultValue: DataLayer.UserProfile?...) -> PropertyStub { + return Given(method: .p_userProfile_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func useRelativeDates(getter defaultValue: Bool...) -> PropertyStub { + return Given(method: .p_useRelativeDates_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func calendarSettings(getter defaultValue: CalendarSettings?...) -> PropertyStub { + return Given(method: .p_calendarSettings_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func hideInactiveCourses(getter defaultValue: Bool?...) -> PropertyStub { + return Given(method: .p_hideInactiveCourses_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func lastLoginUsername(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_lastLoginUsername_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func lastCalendarName(getter defaultValue: String?...) -> PropertyStub { + return Given(method: .p_lastCalendarName_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func lastCalendarUpdateDate(getter defaultValue: Date?...) -> PropertyStub { + return Given(method: .p_lastCalendarUpdateDate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + public static func firstCalendarUpdate(getter defaultValue: Bool?...) -> PropertyStub { + return Given(method: .p_firstCalendarUpdate_get, products: defaultValue.map({ StubProduct.return($0 as Any) })) + } + + } + + public struct Verify { + fileprivate var method: MethodType + + public static var userProfile: Verify { return Verify(method: .p_userProfile_get) } + public static func userProfile(set newValue: Parameter) -> Verify { return Verify(method: .p_userProfile_set(newValue)) } + public static var useRelativeDates: Verify { return Verify(method: .p_useRelativeDates_get) } + public static func useRelativeDates(set newValue: Parameter) -> Verify { return Verify(method: .p_useRelativeDates_set(newValue)) } + public static var calendarSettings: Verify { return Verify(method: .p_calendarSettings_get) } + public static func calendarSettings(set newValue: Parameter) -> Verify { return Verify(method: .p_calendarSettings_set(newValue)) } + public static var hideInactiveCourses: Verify { return Verify(method: .p_hideInactiveCourses_get) } + public static func hideInactiveCourses(set newValue: Parameter) -> Verify { return Verify(method: .p_hideInactiveCourses_set(newValue)) } + public static var lastLoginUsername: Verify { return Verify(method: .p_lastLoginUsername_get) } + public static func lastLoginUsername(set newValue: Parameter) -> Verify { return Verify(method: .p_lastLoginUsername_set(newValue)) } + public static var lastCalendarName: Verify { return Verify(method: .p_lastCalendarName_get) } + public static func lastCalendarName(set newValue: Parameter) -> Verify { return Verify(method: .p_lastCalendarName_set(newValue)) } + public static var lastCalendarUpdateDate: Verify { return Verify(method: .p_lastCalendarUpdateDate_get) } + public static func lastCalendarUpdateDate(set newValue: Parameter) -> Verify { return Verify(method: .p_lastCalendarUpdateDate_set(newValue)) } + public static var firstCalendarUpdate: Verify { return Verify(method: .p_firstCalendarUpdate_get) } + public static func firstCalendarUpdate(set newValue: Parameter) -> Verify { return Verify(method: .p_firstCalendarUpdate_set(newValue)) } + } + + public struct Perform { + fileprivate var method: MethodType + var performs: Any + + } + + public func given(_ method: Given) { + methodReturnValues.append(method) + } + + public func perform(_ method: Perform) { + methodPerformValues.append(method) + methodPerformValues.sort { $0.method.intValue() < $1.method.intValue() } + } + + public func verify(_ method: Verify, count: Count = Count.moreOrEqual(to: 1), file: StaticString = #file, line: UInt = #line) { + let fullMatches = matchingCalls(method, file: file, line: line) + let success = count.matches(fullMatches) + let assertionName = method.method.assertionName() + let feedback: String = { + guard !success else { return "" } + return Utils.closestCallsMessage( + for: self.invocations.map { invocation in + matcher.set(file: file, line: line) + defer { matcher.clearFileAndLine() } + return MethodType.compareParameters(lhs: invocation, rhs: method.method, matcher: matcher) + }, + name: assertionName + ) + }() + MockyAssert(success, "Expected: \(count) invocations of `\(assertionName)`, but was: \(fullMatches).\(feedback)", file: file, line: line) + } + + private func addInvocation(_ call: MethodType) { + self.queue.sync { invocations.append(call) } + } + private func methodReturnValue(_ method: MethodType) throws -> StubProduct { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let candidates = sequencingPolicy.sorted(methodReturnValues, by: { $0.method.intValue() > $1.method.intValue() }) + let matched = candidates.first(where: { $0.isValid && MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch }) + guard let product = matched?.getProduct(policy: self.stubbingPolicy) else { throw MockError.notStubed } + return product + } + private func methodPerformValue(_ method: MethodType) -> Any? { + matcher.set(file: self.file, line: self.line) + defer { matcher.clearFileAndLine() } + let matched = methodPerformValues.reversed().first { MethodType.compareParameters(lhs: $0.method, rhs: method, matcher: matcher).isFullMatch } + return matched?.performs + } + private func matchingCalls(_ method: MethodType, file: StaticString?, line: UInt?) -> [MethodType] { + matcher.set(file: file ?? self.file, line: line ?? self.line) + defer { matcher.clearFileAndLine() } + return invocations.filter { MethodType.compareParameters(lhs: $0, rhs: method, matcher: matcher).isFullMatch } + } + private func matchingCalls(_ method: Verify, file: StaticString?, line: UInt?) -> Int { + return matchingCalls(method.method, file: file, line: line).count + } + private func givenGetterValue(_ method: MethodType, _ message: String) -> T { + do { + return try methodReturnValue(method).casted() + } catch { + onFatalFailure(message) + Failure(message) + } + } + private func optionalGivenGetterValue(_ method: MethodType, _ message: String) -> T? { + do { + return try methodReturnValue(method).casted() + } catch { + return nil + } + } + private func onFatalFailure(_ message: String) { + guard let file = self.file, let line = self.line else { return } // Let if fail if cannot handle gratefully + SwiftyMockyTestObserver.handleFatalError(message: message, file: file, line: line) + } +} + // MARK: - WebviewCookiesUpdateProtocol open class WebviewCookiesUpdateProtocolMock: WebviewCookiesUpdateProtocol, Mock {