Skip to content

Instantly share code, notes, and snippets.

View bocato's full-sized avatar

Eduardo Bocato bocato

View GitHub Profile
@bocato
bocato / mvvm_form_1.swift
Last active March 27, 2021 11:42
mvvm_form_1.swift
import Combine
import SwiftUI
struct ExampleState: Equatable {
var email: String = ""
var password: String = ""
var passwordError: String?
var isSignUpButtonEnabled: Bool = false
}
@bocato
bocato / StateBindingViewModel.swift
Last active March 27, 2021 10:35
Helper to simplify Forms / Binding on SwiftUI MVVM
import Combine
import SwiftUI
/* -------------- */
/* Implementation */
/* -------------- */
/// Represents a helper to simplify creating bindings to the `State` on the MVVM architecture.
/// Initially create to simplfy forms, but can be applied on other secenarios.
/// Example:
@bocato
bocato / TestingFatalError.swift
Created February 24, 2021 22:16
Testing Fatal Errors
import Foundation
/*********************************************/
/* Add on the target that calls `fatalError` */
/*********************************************/
/// This replaces the system's `fatalError` implementation, calling our util in order to make it
/// possible for us to capture it's parameters, results and such, then unit test our fatal errors 🎉
func fatalError(_ message: @autoclosure () -> String = "", file: StaticString = #file, line: UInt = #line) -> Never {
FatalErrorUtil.fatalErrorClosure(message(), file, line)
@bocato
bocato / SimpleDI.swift
Last active February 24, 2021 17:20
Simple dependency Injection with containers and property wrappers
import Foundation
/// Defines a factory that builds a dependency
public typealias DependencyFactory = () -> Any
/// Defines a contract for a dependency container
public protocol DependenciesContainerInterface: AnyObject {
/// Get's a dependency from the container
/// - Parameter arg: the type of the dependency
func get<T>(_ arg: T.Type) -> T?
final class UserServiceStub: UserServiceProtocol {
var loginResultToBeReturned: Result<Void, Error> = .success(())
func login(_ user: User, then: (Result<Void, Error>) -> Void) {
then(loginResultToBeReturned)
}
}
final class SafeStorageSpy: SafeStorageProtocol {
private(set) var storeUserDataCalled = false
private(set) var userPassed: User?
struct User: Equatable {
let name: String
let password: String
}
protocol UserServiceProtocol {
func login(_ user: User, then: (Result<Void, Error>) -> Void)
}
protocol SafeStorageProtocol {
final class PostsServiceStub: PostsServiceProtocol {
var fetchAllResultToBeReturned: Result<[Post], Error> = .success([])
func fetchAll(then: (Result<[Post], Error>) -> Void) {
then(fetchAllResultToBeReturned)
}
}
// Uso
final class UserFeedViewModelTests: XCTestCase {
func test_fetchAll_shouldReturnTheCorrectAmountOfPosts() {
struct Post {
let title: String
let text: String
}
protocol PostsServiceProtocol {
func fetchAll(then: (Result<[Post], Error>) -> Void)
}
final class UserFeedViewModel {
final class FavoritesManagerFake: FavoritesManagerProtocol {
var favorites: [Movie] = []
func add(_ movie: Movie) throws {
guard !favorites.contains(where: { $0.id == movie.id } ) else {
throw NSError(domain: "FavoritesManagerFake", code: -1, userInfo: nil)
}
favorites.append(movie)
}
struct Movie {
let id: String
let name: String
let posterURL: String
}
protocol FavoritesManagerProtocol {
func add(_ movie: Movie) throws
func remove(_ movie: Movie) throws
var favorites: [Movie] { get }
}