-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create mocks for push messaging (#35)
- Loading branch information
1 parent
fc67e44
commit b2c5d62
Showing
15 changed files
with
736 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
120 changes: 120 additions & 0 deletions
120
Sources/MessagingPush/autogenerated/AutoDependencyInjection.generated.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery | ||
// DO NOT EDIT | ||
// swiftlint:disable all | ||
|
||
import CioTracking | ||
import Foundation | ||
|
||
// File generated from Sourcery-DI project: https://github.com/levibostian/Sourcery-DI | ||
// Template version 1.0.0 | ||
|
||
/** | ||
###################################################### | ||
Documentation | ||
###################################################### | ||
|
||
This automatically generated file you are viewing is a dependency injection graph for your app's source code. | ||
You may be wondering a couple of questions. | ||
|
||
1. How did this file get generated? Answer --> https://github.com/levibostian/Sourcery-DI#how | ||
2. Why use this dependency injection graph instead of X other solution/tool? Answer --> https://github.com/levibostian/Sourcery-DI#why-use-this-project | ||
3. How do I add dependencies to this graph file? Follow one of the instructions below: | ||
* Add a non singleton class: https://github.com/levibostian/Sourcery-DI#add-a-non-singleton-class | ||
* Add a generic class: https://github.com/levibostian/Sourcery-DI#add-a-generic-class | ||
* Add a singleton class: https://github.com/levibostian/Sourcery-DI#add-a-singleton-class | ||
* Add a class from a 3rd party library/SDK: https://github.com/levibostian/Sourcery-DI#add-a-class-from-a-3rd-party | ||
* Add a `typealias` https://github.com/levibostian/Sourcery-DI#add-a-typealias | ||
|
||
4. How do I get dependencies from the graph in my code? | ||
``` | ||
// If you have a class like this: | ||
class OffRoadWheels {} | ||
|
||
class ViewController: UIViewController { | ||
// Call the property getter to get your dependency from the graph: | ||
let wheels = DIMessagingPush.shared.offRoadWheels | ||
// note the name of the property is name of the class with the first letter lowercase. | ||
|
||
// you can also use this syntax instead: | ||
let wheels: OffRoadWheels = DIMessagingPush.shared.inject(.offRoadWheels) | ||
// although, it's not recommended because `inject()` performs a force-cast which could cause a runtime crash of your app. | ||
} | ||
``` | ||
|
||
5. How do I use this graph in my test suite? | ||
``` | ||
let mockOffRoadWheels = // make a mock of OffRoadWheels class | ||
DIMessagingPush.shared.override(.offRoadWheels, mockOffRoadWheels) | ||
``` | ||
|
||
Then, when your test function finishes, reset the graph: | ||
``` | ||
DIMessagingPush.shared.resetOverrides() | ||
``` | ||
|
||
*/ | ||
|
||
/** | ||
enum that contains list of all dependencies in our app. | ||
This allows automated unit testing against our dependency graph + ability to override nodes in graph. | ||
*/ | ||
public enum DependencyMessagingPush: CaseIterable { | ||
case diPlaceholder | ||
} | ||
|
||
/** | ||
Dependency injection graph specifically with dependencies in the MessagingPush module. | ||
|
||
We must use 1+ different graphs because of the hierarchy of modules in this SDK. | ||
Example: You can't add classes from `Tracking` module in `Common`'s DI graph. However, classes | ||
in `Common` module can be in the `Tracking` module. | ||
*/ | ||
public class DIMessagingPush { | ||
public static var shared = DIMessagingPush() | ||
private var overrides: [DependencyMessagingPush: Any] = [:] | ||
private init() {} | ||
|
||
/** | ||
Designed to be used only in test classes to override dependencies. | ||
|
||
``` | ||
let mockOffRoadWheels = // make a mock of OffRoadWheels class | ||
DIMessagingPush.shared.override(.offRoadWheels, mockOffRoadWheels) | ||
``` | ||
*/ | ||
public func override<Value: Any>(_ dep: DependencyMessagingPush, value: Value, forType type: Value.Type) { | ||
overrides[dep] = value | ||
} | ||
|
||
/** | ||
Reset overrides. Meant to be used in `tearDown()` of tests. | ||
*/ | ||
public func resetOverrides() { | ||
overrides = [:] | ||
} | ||
|
||
/** | ||
Use this generic method of getting a dependency, if you wish. | ||
*/ | ||
public func inject<T>(_ dep: DependencyMessagingPush) -> T { | ||
switch dep { | ||
case .diPlaceholder: return diPlaceholder as! T | ||
} | ||
} | ||
|
||
/** | ||
Use the property accessors below to inject pre-typed dependencies. | ||
*/ | ||
|
||
// DiPlaceholder | ||
internal var diPlaceholder: DiPlaceholder { | ||
if let overridenDep = overrides[.diPlaceholder] { | ||
return overridenDep as! DiPlaceholder | ||
} | ||
return newDiPlaceholder | ||
} | ||
|
||
private var newDiPlaceholder: DiPlaceholder { | ||
DiPlaceholder() | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
Sources/MessagingPush/autogenerated/AutoLenses.generated.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery | ||
// DO NOT EDIT | ||
// swiftlint:disable all | ||
|
||
import CioTracking | ||
import Foundation | ||
|
||
/** | ||
###################################################### | ||
Documentation | ||
###################################################### | ||
|
||
This automatically generated file you are viewing is to modify immutable objects in a convenient way. | ||
|
||
* What do you mean modify immutable objects? https://apiumhub.com/tech-blog-barcelona/lenses-swift-immutability-objects/ | ||
|
||
* How do I use this? | ||
|
||
``` | ||
// Add `AutoLenses` protocol to struct. | ||
struct Foo: AutoLenses { | ||
// properties be `let` to be immutable | ||
let bar: String | ||
let bar2: Bool | ||
} | ||
|
||
var foo = Foo(bar: "X", bar2: true) | ||
// Now, we want to modify `foo.bar` but it's immutable. How do I modify `bar` without having to do something messy like... | ||
Foo(bar: "new value", bar2: oldInstance.bar2) | ||
...to leave my other properties alone? | ||
|
||
foo = foo.setBar("new value") | ||
// Now, `foo` is set to the brand new instanced of `Foo` while copying over all other values of `Foo` from the old instance. | ||
``` | ||
|
||
*/ | ||
|
||
infix operator *~: MultiplicationPrecedence | ||
infix operator |>: AdditionPrecedence | ||
|
||
struct Lens<Whole, Part> { | ||
let get: (Whole) -> Part | ||
let set: (Part, Whole) -> Whole | ||
} | ||
|
||
func * <A, B, C>(lhs: Lens<A, B>, rhs: Lens<B, C>) -> Lens<A, C> { | ||
Lens<A, C>(get: { a in rhs.get(lhs.get(a)) }, | ||
set: { c, a in lhs.set(rhs.set(c, lhs.get(a)), a) }) | ||
} | ||
|
||
func *~ <A, B>(lhs: Lens<A, B>, rhs: B) -> (A) -> A { | ||
{ a in lhs.set(rhs, a) } | ||
} | ||
|
||
func |> <A, B>(x: A, f: (A) -> B) -> B { | ||
f(x) | ||
} | ||
|
||
func |> <A, B, C>(f: @escaping (A) -> B, g: @escaping (B) -> C) -> (A) -> C { | ||
{ g(f($0)) } | ||
} |
149 changes: 149 additions & 0 deletions
149
Sources/MessagingPush/autogenerated/AutoMockable.generated.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Generated using Sourcery 1.5.0 — https://github.com/krzysztofzablocki/Sourcery | ||
// DO NOT EDIT | ||
// swiftlint:disable all | ||
|
||
import Foundation | ||
#if canImport(FoundationNetworking) | ||
import FoundationNetworking | ||
#endif | ||
import CioTracking | ||
|
||
/** | ||
###################################################### | ||
Documentation | ||
###################################################### | ||
|
||
This automatically generated file you are viewing contains mock classes that you can use in your test suite. | ||
|
||
* How do you generate a new mock class? | ||
|
||
1. Mocks are generated from Swift protocols. So, you must make one. | ||
|
||
``` | ||
protocol FriendsRepository { | ||
func acceptFriendRequest<Attributes: Encodable>(attributes: Attributes, _ onComplete: @escaping () -> Void) | ||
} | ||
|
||
class AppFriendsRepository: FriendsRepository { | ||
... | ||
} | ||
``` | ||
|
||
2. Have your new protocol extend `AutoMockable`: | ||
|
||
``` | ||
protocol FriendsRepository: AutoMockable { | ||
func acceptFriendRequest<Attributes: Encodable>( | ||
// sourcery:Type=Encodable | ||
attributes: Attributes, | ||
_ onComplete: @escaping () -> Void) | ||
} | ||
``` | ||
|
||
> Notice the use of `// sourcery:Type=Encodable` for the generic type parameter. Without this, the mock would | ||
fail to compile: `functionNameReceiveArguments = (Attributes)` because `Attributes` is unknown to this `var`. | ||
Instead, we give the parameter a different type to use for the mock. `Encodable` works in this case. | ||
It will require a cast in the test function code, however. | ||
|
||
3. Run the command `make generate` on your machine. The new mock should be added to this file. | ||
|
||
* How do you use the mocks in your test class? | ||
|
||
``` | ||
class ExampleViewModelTest: XCTestCase { | ||
var viewModel: ExampleViewModel! | ||
var exampleRepositoryMock: ExampleRepositoryMock! | ||
override func setUp() { | ||
exampleRepositoryMock = ExampleRepositoryMock() | ||
viewModel = AppExampleViewModel(exampleRepository: exampleRepositoryMock) | ||
} | ||
} | ||
``` | ||
|
||
Or, you may need to inject the mock in a different way using the DI.shared graph: | ||
|
||
``` | ||
class ExampleTest: XCTestCase { | ||
var exampleViewModelMock: ExampleViewModelMock! | ||
var example: Example! | ||
override func setUp() { | ||
exampleViewModelMock = ExampleViewModelMock() | ||
DI.shared.override(.exampleViewModel, value: exampleViewModelMock, forType: ExampleViewModel.self) | ||
example = Example() | ||
} | ||
} | ||
|
||
``` | ||
|
||
*/ | ||
|
||
/** | ||
Class to easily create a mocked version of the `MessagingPushInstance` class. | ||
This class is equipped with functions and properties ready for you to mock! | ||
|
||
Note: This file is automatically generated. This means the mocks should always be up-to-date and has a consistent API. | ||
See the SDK documentation to learn the basics behind using the mock classes in the SDK. | ||
*/ | ||
public class MessagingPushInstanceMock: MessagingPushInstance { | ||
/// If *any* interactions done on mock. `true` if any method or property getter/setter called. | ||
public var mockCalled: Bool = false // | ||
|
||
// MARK: - registerDeviceToken | ||
|
||
/// Number of times the function was called. | ||
public private(set) var registerDeviceTokenCallsCount = 0 | ||
/// `true` if the function was ever called. | ||
public var registerDeviceTokenCalled: Bool { | ||
registerDeviceTokenCallsCount > 0 | ||
} | ||
|
||
/// The arguments from the *last* time the function was called. | ||
public private(set) var registerDeviceTokenReceivedArguments: (deviceToken: Data, | ||
onComplete: (Result<Void, CustomerIOError>) -> Void)? | ||
/// Arguments from *all* of the times that the function was called. | ||
public private(set) var registerDeviceTokenReceivedInvocations: [(deviceToken: Data, | ||
onComplete: (Result<Void, CustomerIOError>) | ||
-> Void)] = [] | ||
/** | ||
Set closure to get called when function gets called. Great way to test logic or return a value for the function. | ||
*/ | ||
public var registerDeviceTokenClosure: ((Data, (Result<Void, CustomerIOError>) -> Void) -> Void)? | ||
|
||
/// Mocked function for `registerDeviceToken(_ deviceToken: Data, onComplete: @escaping (Result<Void, CustomerIOError>) -> Void)`. Your opportunity to return a mocked value and check result of mock in test code. | ||
public func registerDeviceToken(_ deviceToken: Data, | ||
onComplete: @escaping (Result<Void, CustomerIOError>) -> Void) | ||
{ | ||
mockCalled = true | ||
registerDeviceTokenCallsCount += 1 | ||
registerDeviceTokenReceivedArguments = (deviceToken: deviceToken, onComplete: onComplete) | ||
registerDeviceTokenReceivedInvocations.append((deviceToken: deviceToken, onComplete: onComplete)) | ||
registerDeviceTokenClosure?(deviceToken, onComplete) | ||
} | ||
|
||
// MARK: - deleteDeviceToken | ||
|
||
/// Number of times the function was called. | ||
public private(set) var deleteDeviceTokenCallsCount = 0 | ||
/// `true` if the function was ever called. | ||
public var deleteDeviceTokenCalled: Bool { | ||
deleteDeviceTokenCallsCount > 0 | ||
} | ||
|
||
/// The arguments from the *last* time the function was called. | ||
public private(set) var deleteDeviceTokenReceivedArguments: ((Result<Void, CustomerIOError>) -> Void)? | ||
/// Arguments from *all* of the times that the function was called. | ||
public private(set) var deleteDeviceTokenReceivedInvocations: [(Result<Void, CustomerIOError>) -> Void] = [] | ||
/** | ||
Set closure to get called when function gets called. Great way to test logic or return a value for the function. | ||
*/ | ||
public var deleteDeviceTokenClosure: (((Result<Void, CustomerIOError>) -> Void) -> Void)? | ||
|
||
/// Mocked function for `deleteDeviceToken(onComplete: @escaping (Result<Void, CustomerIOError>) -> Void)`. Your opportunity to return a mocked value and check result of mock in test code. | ||
public func deleteDeviceToken(onComplete: @escaping (Result<Void, CustomerIOError>) -> Void) { | ||
mockCalled = true | ||
deleteDeviceTokenCallsCount += 1 | ||
deleteDeviceTokenReceivedArguments = onComplete | ||
deleteDeviceTokenReceivedInvocations.append(onComplete) | ||
deleteDeviceTokenClosure?(onComplete) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.